I'm loading images into a TableView using Apple's lazy loader code example. Since the view controller is in a nav stack, the user can scroll quickly and then tap back and navigate out of the view. The VC is a delegate of the IconDownloader class, the class doing the image downloading, and I am setting the IconDownloader delegate to nil in the VC dealloc.
However there is a timing issue where the scroll delegate scrollViewDidEndDecelerating fires, which fires image loading, but in between my viewWillDisappear fires but the image loading event is already queued up. This causes a crash as the view is gone, as is the delegate, but the IconDownloader fires its delegate method anyway.
So order as follows:
- scrollViewDidEndDecelerating (which calls loadImagesForOnscreenRows)
- viewWillDisappear
- loadImagesForOnscreenRows
I'm also checking the delegate status in IconDownloader with respondsToSelector and not nil.
So I ended up setting a bool in viewWillDisappear as well as setting the delegate to nil. Then in loadImagesForOnscreenRows I check the bool. I feel like there is a better way to do this but everything I've read indicates I'm disposing of the delegate properly. Most posts recommend NOT retaining the delegate from IconDownloader. Just wondering what others think of this solution. Thanks!
Code:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}
- (void)loadImagesForOnscreenRows
{
if ([self.entries count] > 0 && !viewIsDisappearing)
{
...
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
viewIsDisappearing = TRUE;
self.iconDownloader.delegate = nil;
}
and in IconDownloader NSURL connectionDidFinishLoading:
// call our delegate and tell it that our icon is ready for display
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(appImageDidLoad:)])
{
[delegate appImageDidLoad:self.indexPathInTableView];
}