views:

35

answers:

2

I had a data loader send a message to its delegate when its done

- (void) loadingMethod {
    // Loading stuff...
    [delegate LoaderDidFinish];
}

The delegate then relases the loader that called it, then does some stuff.

- (void) LoaderDidFinish {
   [Loader release];
   // Do stuff
}

This caused a bad acces error.

I assuemed this was cause because after LoaderDidFinish finished control returned to the loadingMethod which had been released.

However what suppried me was the fact that releasing the Loader later on in the method fixed the problem:

- (void) LoaderDidFinish {
   // Do stuff
   [Loader release];  // Now there is no bad access error!
}

Can someone explain why this worked?

+2  A: 

Something in your // Do stuff uses some part of Loader.

In general, I'm not sure it's optimal to release an object from it's delegate. But if you must, an autorelease would have avoided this problem.

calmh
+2  A: 

It is just pure luck that you do not get any bad access errors by moving the call to release.

If you need to release the loader after you get the callback, it should either be deferred in the runloop, eg. by using [self performSelector:@selector(deferredLoaderDelete) withObject:nil afterDelay:0.0f] or by autoreleasing the loader in the callback.

Claus Broch
The autorelease unfortunately didn't seam to work, I think because the loader itself uses asynchronous calls. I think ill add the 'relaese delay' solution although it looks a bit hacky.
Robert
If autorelease doesn't work but releasing at the end does, you're doing something wrong.
tc.