Original address: http://zhangbuhuai.com/2015/02/11/common picture buffering strategy
It 's written in front .
"Download Picture" is almost every mobile app to deal with the problem, for the iOS development platform, downloading pictures is not a complex thing, given a URL, and then use the URL-related library (such as afnetworking) to take out the picture, but from the user's point of view, Relative to the text information, download pictures often bring more costs (long download time, large traffic, etc.), so there are still a lot of problems need developers to consider, such as local caching, URL caching, server compression and client decompression, and sometimes there are performance considerations.
The author is currently in touch with the development of the app is not particularly high performance requirements, so the focus needs to consider the picture flow problem, in short, the need to do is to do as little as possible through the network from the server to download pictures, so this article mainly talk about the image caching mechanism.
The author uses the picture caching frame for a long time is Uiimageview (afnetworking), but does not use directly, but changes according to own need, makes it more perfect; another highly acclaimed and widely used picture caching framework is sdwebimage, This paper also collates the caching mechanism for later use. My picture caching strategy
Specifically, picture caching typically consists of two parts: URL caching and storage caching, or "Memory Caching" and "local caching." The former stores the picture in memory, and the latter stores the picture on the local disk. Therefore, when the Uiimageview control needs to load a picture, the picture source can be three places: memory, local disk, network server, and consumption cost sort also: Memory < Local Disk < network server.
Uiimageview (afnetworking) is not complete, it only does "URL caching", and does not do "storage cache", in addition, it is more coarse to "URL cache" processing. Take a chestnut, now app needs to download the URL for http://example.com/test.png picture and "loaded" into the Uiimageview control, Uiimageview (afnetworking) processing strategy is: Download the picture through the network; Save the download picture in memory, stored in the form of a key value pair, key for url,value for download picture, when again need to load the URL for http://example.com/test.png picture, to the memory of the picture to find out, directly "loaded" Into the Uimageview control without having to download it over the network.
But on many occasions, at different times the same URL of the corresponding picture is not the same, such as user avatar, assuming that its user ID is 123456, then its avatar URL is usually http://example.com/123456/123456.png, Users can generally customize the avatar, so the image of this address is often changed ... The author's experience of the project is: when the client to the server to the picture information, servers returned picture information at least two parts: Picture URL and the image of the hash value (in the server, each picture has its own hash value). In this case, the client does not just need to check the URL, but also check the hash value when detecting whether the picture is in memory.
In short, for the author of the project, Uiimageview (afnetworking) There are two deficiencies: "URL cache" is too rough; there is no "storage cache";
The author of these two deficiencies on the Uiimageview (afnetworking) processing, the final caching strategy is: According to the image URL and hash value to find whether the cache has this picture. If not, enter the 2nd step; if so, further determine whether the hash value of the picture is the same as that in the cache, and if not, go to step 2nd; Find the physical storage (local disk) based on the image hash value if there is a picture, then return the picture, and then enter the 3rd step; Download the picture from the network, save it to memory and local disk after downloading, the former uses Nscache to store, the storage information includes: Picture URL, picture hash value, picture; the picture that is stored on the local disk is named "hash value of the picture. png". Sdwebimage's image caching strategy
Sdwebimage is a very powerful frame for image caching. Afnetworking integrated uiimageview+afnetworking.h for the image of the actual application of the cache is nsurlcache with the cache mechanism. and nsurlcache the cached raw data into uiimage each time, which brings more operations in data processing and memory. Concrete comparisons are here.
Sdwebimage provides the following three category for caching: Mkannotationview (Webcache) UIButton (Webcache) Uiimageview (Webcache)
Take the most commonly used Uiimageview (Webcache) as an example: SetImageWithURL:placeholderImage:options: First show Placeholderimage, At the same time by sdwebimagemanager based on the URL to find the local picture; SDWebImageManager:downloadWithURL:delegate:options:userInfo: Sdwebimagemanager is a class that links Uiimageview+webcache with Sdimagecache, SDImageCache:queryDiskCacheForKey:delegate:userInfo : Used to find whether a picture is already in the cache from the cache, and if there is already a picture cache in memory, Sdwebimagemanager will recall the SDImageCacheDelegate:imageCache:didFindImage: CacheKey Forkey:userinfo:; and Uiimageview+webcache callback SDWebImageManagerDelegate:webImageManager:didFinishWithImage: to display the picture; If there is no picture cache in memory, the build nsinvocationoperation is added to the queue, the hard disk finds out if the picture has been downloaded, and an attempt is made to read the picture file under Urlkey in the hard disk cache directory. This step is done in nsoperation, so back to the main thread for the result callback notifydelegate:; If the previous operation read the picture from the hard disk, add the picture to the memory cache (if the free memory is too small, the memory cache is emptied first). Sdimagecachedelegate callback ImageCache:didFindImage:forKey:userInfo: And then callback the display picture; If the picture is not read from the hard disk cache directory, the picture is not present in all caches, the picture needs to be downloaded, and the callback ImageCache:didNotFindImageForKey:userInfo:; share or regenerate a download sdwebimagedownloader start downloading pictures; Download by nsurlconnection Implement related delegate to judge picture downloading, download completion and download failure; Connection:didreceivedata: In the use of ImageIO did the download progress by picture loading effectConnectiondidfinishloading: After the data downloading completes, gives sdwebimagedecoder to do the picture decoding processing, the image decoding processing completes in a nsoperationqueue, does not drag slow main thread UI, If there is a need to download the picture for two processing, it is best to complete here, the efficiency will be much better; in the main thread Notifydelegateonmainthreadwithinfo: decoding complete, Imagedecoder: Didfinishdecodingimage:userinfo: Callback to Sdwebimagedownloader; Imagedownloader:didfinishwithimage: Callback to Sdwebimagemanager told the picture download completed, notify all downloaddelegates download complete, callback to the required place to display the picture, save the picture to the Sdimagecache, memory cache and hard disk cache save simultaneously; Write files to the hard drive in a separate nsinvocationoperation to avoid dragging the main thread; if it's running on iOS, Sdimagecache will register notification to uiapplicationdidreceivememorywarningnotification and Uiapplicationwillterminatenotificati at initialization time. On, clean up the memory picture cache at the time of memory warning, and clean out the outdated picture when the application finishes; Sdwebimageprefetcher can download pictures beforehand to facilitate subsequent use;
There is no doubt that Sdwebimage is much more powerful than Uiimageview (afnetworking), but it has become more complicated and more troublesome to use; In my opinion, for simpler occasions, considering the convenience of use, Uiimageview ( afnetworking) would be a better choice.
Reference: "Sdwebimage caching image Mechanism"