Reputation: 3140
After transitioning a project to ARC, I've been having some issues with delegate methods not being called/being called on deallocated instances. I've realized that the problem is that I have a variable that gets allocated and then executes an asynchronous task. For a simple example, assume that there is an object called MyService that responds to a delegate method, executeDidSucceed:
- (void)fireRequest {
MyService *service = [[MyService alloc] initWithDelegate:self];
[service execute];
}
The original code would look something like this:
- (void)fireRequest {
MyService *service = [[[MyService alloc] initWithDelegate:self] autorelease];
[service execute];
}
With ARC, I understand that a release
call gets added after [service execute]
gets called. And I also understand that because the method is asynchronous, the service
object will get deallocated, and a call to the deallocated object will be made for the delegate method.
I know a solution would be to make service
an instance variable and give it the strong
property so we can retain ownership of it. And I know of a solution where we could create a block and use a completion handler so the delegate stays retained until the block is completed. My question is, what's the best way of handling a situation like this? Or more so, what's the "best practice" for resolving this while transitioning to ARC?
Upvotes: 3
Views: 199
Reputation: 5552
You will need to make your Myservice object a member to this class. ARC is cleaning it up as soon as this function completes because you no longer have a reference to it.
It's also my opinion that its a good practice to do since you don't have a reference to that object until it calls a delegate (if it does) and depending on the situation you may need stop the service before it completes.
Upvotes: 4