Reputation: 13
I use GCD to fetch some images from the Internet in a new queue using dispatch_queueu_create
. Then I go back to the main queue and update the UIImageView
with the fetched image by using dispatch_async
. I am using self.imageView
to reference to the UIImageView
in the main queue.
However, sometimes the image takes some time to load from the Internet. If the user clicks somewhere and the view controller changes to something else, I found some weird behavior or my app even crashes. I guess the reason is that I am referencing to self.imageView but the current view controller doesn't have that property. Or any other possibilities? Any suggestions to fix that?
Thanks in advance!
Sorry that I didn't include code here. Here is the code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
dispatch_queue_t photoFetchQueue = dispatch_queue_create("photo data downloader", NULL);
dispatch_async(photoFetchQueue, ^{
NSURL *photoURL = ...;
NSData *photoData = ...;
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = [UIImage imageWithData:photoData];
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
self.scrollView.zoomScale = 1.0;
self.scrollView.contentSize = self.imageView.image.size;
[scrollView zoomToRect:imageView.frame animated:YES];
});
});
dispatch_release(photoFetchQueue);
}
Upvotes: 1
Views: 356
Reputation: 162712
You need a cancellation pattern. That is, you need to be able to cancel the background task. Without code, hard to say what the best approach would be. If you used the higher level NSOperation API, it has cancellation support.
For Blocks/GCD, you'd probably want to have an "isCanceled" on some object somewhere -- preferably on the object that represents the background fetch -- and then check that, when possible, to determine if the response is still relevant.
Upvotes: 4