SpacePyro
SpacePyro

Reputation: 3140

Transitioning to ARC causing delegate issues

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

Answers (1)

rooster117
rooster117

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

Related Questions