Generally speaking, if an asynchronous method takes some kind of target/action callback, it should keep a reference to the target so it can be sure its still around when it fires the callback.
On the other hand, its often conventional for delegates of a class to not be retained; in this case, it is vital that the calling class ensures that it removes itself as the delegate of anything else in its dealloc method.
Here's a trivial example, involving a UIViewController that acts as a delegate to a NSURLConnection. Whilst delegates are typically assigned rather than retained, NSURLConnection will retain your view controller when you pass it in as the delegate. It will not release it until the connection has finished/cancelled/errored.
// connection is an instance variable in your controller sub-class
connection = [[NSURLConnection alloc] initWithRequest:someRequest delegate:self];
// implement various NSURLConnectionDelegate methods etc.
Because it is retained, it shouldn't be possible for your view controller to be dealloced until the connection is finished.
So what about when a delegate isn't retained, as is normally the case? That means something could cause your view controller to be released and dealloced before whatever object is using it is finished. It is your view controller's responsibility to make sure this doesn't happen by resetting the delegate back to nil:
someDownloadManager = [[MyDownloadManager alloc] init];
someDownloadManager.delegate = self; // delegate is an assigned property
[someDownloadManager startDownloading];
In your view controller's dealloc:
- (void)dealloc
{
someDownloadManager.delegate = nil; // this is important
[someDownloadManager release]; // it might still be retained by something else!
[super dealloc];
}
For the same reason, if your object registers itself as an observer with NSNotificationCenter, it should also remove itself as an observer in its dealloc method.
Does that help?