Question

I have a UIImageView. The image for this imageView is loading from web. Can someone please tell me how to stop the loading?

This is my code:

UIImageView *currentImgView = (UIImageView *)[self.scrollView viewWithTag:self.pageControl.currentPage + 500];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            UIImage *newImg = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[[[self.imagesStructure valueForKey:DATA_PARAMETER] objectAtIndex:self.pageControl.currentPage] valueForKey:@"source"]]]];
            dispatch_async(dispatch_get_main_queue(), ^{
                currentImgView.image = newImg;
                [self hideActivityView];
            });

        }); 
Was it helpful?

Solution

You cannot do this with dataWithContentsOfURL:. You will need to switch to downloading the data with NSURLConnection rather than a dispatch_async. You can then call [connection cancel] to stop the download. See the URL Loading System for full details on setting this up.

Note that in most cases, it's not worth the trouble to cancel downloads unless the file is quite large. By the time you've gotten around to canceling, the data is often already in flight, and you might as well just throw it away rather than try to cancel (because you're going to get it anyway).

To implement this approach, you would check for cancellation right before your currentImgView.image = newImg line. You should generally do this anyway (since it's possible the download was cancelled between the time you downloaded it and the time the main queue ran again). A good way to attack this problem is with an NSOperaration, since it gives you access to a convenient cancel method. Note that canceling an operation just sets a flag. It's up to you to check that that flag and stop processing.

OTHER TIPS

We can walk you through how to create cancelable network requests (e.g. NSURLConnectionDataDelegate-based requests), ideally wrapping it in a NSOperation-based implementation rather than GCD, to facilitate the cancelation process (and control the degree of concurrency). But there's a lot of work and special considerations there, and I'm not sure I'd recommend going down that road.

It's much easier to use one of the UIImageView categories out there (SDWebImage is great, AFNetworking's is ok). If you use one of those UIImageView categories, it becomes as simple as:

[currentImgView setImageWithURL:url];

That will not only load the image asynchronously, but when you remove the image view (or request another image) it will cancel the previous network request. Or you can explicitly cancel it (cancelCurrentImageLoad with SDWebImage; cancelImageRequestOperation with AFNetworking). It will also cache responses (so if you come back to the same image 5 times, it will only have to request it once from the network).

If you really want to "roll your own", you can do that (and we can point you in the right direction), but you'll thank yourself if you just avail yourself of one of these existing UIImageView categories.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top