Reputation: 15031
Suppose your controller is a table view and one of the cells you are going off to do a length task (say download a thumbnail) to be viewed in the cell. Typically you would have the network call do a callback to your controller when it is done downloading. The callback can then reload the table or do some other form of UI update (hides a spinner etc).
However, what if the controller is unloaded? Say the user navigated away from this controller and it got released? What happens? Will the callback still work despite the controller now not in memory? Also, if the callback operates on some objects (say the UITableView) what happens when the controller is deallocated? I suppose the controller can release all the objects and the callback would just be calling methods on nil to prevent crash. But is this the convention?
Upvotes: 0
Views: 178
Reputation: 1513
To solve the problem of data arriving while the tableView is NOT loaded:
In the Data-Object-Model paradigm, the view should not have to be loaded for the data to be accepted and stored. When the view (Table or whatever) is later viewed again, it should go and get the data if it is available. Calling UITableView reloadData in your viewWillAppear in the tableViewController class is sometimes a good idea, just depends on your architecture.
To solve the problem of data arriving while the view IS visible and loaded: Once the data has arrived and is available, loop through your TableViewControllers and send them a "reloadData".
Upvotes: 1
Reputation: 10555
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?
Upvotes: 2