问题
There are many third parties libraries for loading a network image and then store it into a disk and/or memory.
However it is very easy to implement it using simple NSURLSession API call.
here is the code:
NSURLCache *myCache = [[NSURLCache alloc] initWithMemoryCapacity: 16384 diskCapacity: 268435456 diskPath: cachePath]; // these numbers are only for the usage example.
defaultConfigObject.URLCache = myCache;
defaultConfigObject.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
_session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
_dataTask = [_session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (!error){
UIImage* theImage = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
self.image = theImage;
});
}
}];
[_dataTask resume];
This code downloads an image(from a given url) and store it to memory+disk according to the http caching policy.
Deriving MyNetworkImageView from UIImageView and adding the above code to a setURL: method, is also straight forward.
My question is:
What are the advantages of using other third parties frameworks such as AFNetworking,FastImageCache,SDWebImage,SDImageCache?
回答1:
Caching in these frameworks is more deterministic. The
NSURLCache
used byNSURLSession
is (a) somewhat opaque (e.g. I've never seen the 5% threshold documented); and (b) controlled by the response headers provided by your server.Before you simply declare
NSURLCache
"good enough", I would suggest rigorously testing the app and make sure the caching (esp persistent storage cache: run the app, download images; terminate (not just suspend) the app; re-run the app) is working like you hope it is. Make sure to test both runtime cacheing as well as persistent storage cacheing.As an aside, your memory cache seems is really small (and anything exceeding 5% of cache size won't get cached). It's a matter of opinion, but I'd generally expect to see something closer to 16mb rather than 16kb. As it is, this won't cache anything exceeding 800 bytes or so!
These frameworks offer many other advantages, too.
The
UIImageView
categories provided by AFNetworking and SDWebImage are the easiest way to achieve asynchronous image retrieval. In particular, when cells are reused in table/collection view, it will cancel the prior requests, making sure that the image requests for visible cells are prioritized. (You don't want to quickly scroll to 100th row in table and have to wait for 99 no-long-visible images to download before you start downloading the images for the visible cells.)If generating complex HTTP requests, AFNetworking lets you focus on the app logic rather than writing and testing complex networking code.
Bottom line, relying upon NSURLCache in iOS has been problematic in the past, especially if you don't control the server. These classes offer other advantages, too (e.g. with UIImageView categories).
回答2:
NSURLCache is a great tool, especially when you need revalidation mechanisms, and NSURLCache handles HTTP revalidation transparently for you. NSURLSession is also a good step forward for Cocoa networking.
However, it's not that easy to implement image fetching in an efficient way. There are some special requirements that you might have in you app:
- Avoid image decompression on the main thread, which is costly, especially for jpg.
- Have a separate in-memory cache layer on top of NSURLCache to store decompressed images, and be able to retrieve them synchronously on the main thread. Managing in-memory cache it not that simple either, even if you use NSCache.
- Have some abstraction on top on networking layer in order to be able to add support for more image formats when necessary, like
gif
orwebp
. And extend image fetching in other ways. - Group same image requests and not create excessive session tasks
- Be able to preheat images efficiently
- Have a way to fetch low-resolution placeholder first and then wait for the high-resolution image
And more.
AFNetworking,FastImageCache,SDWebImage,SDImageCache
Neither of those frameworks use NSURLSession (some even have their own disk cache implementations), please check out Nuke / DFImageManager instead. It's built on top of NSURLSession, it has all the above features, and it also has multiple subspecs that integrate things like AFNetworking* as a networking stack, and FLAnimatedImage as an animated GIF engine, and more.
*AFNetworking is based on NSRULSession, but their image fetching implementation is still based on top of NSURLConnection (AFHTTPRequestOperation).
来源:https://stackoverflow.com/questions/31368831/nsurlsession-for-network-images-downloadcache