SDWebImage is an open source third-party library that provides a taxonomy of UIImageView to support the ability to download and cache images from remote servers. It has the following features (Github bio) :

Provides a class of UIImageView to support web image loading and cache management

An asynchronous picture loader

An asynchronous memory + disk image cache

Support for GIF images

Support WebP images

Background image decompression processing

Ensure that images from the same URL are not downloaded more than once (action queue)

Ensure that bogus urls are not loaded repeatedly

Ensure that the main thread is not blocked when downloading and caching (asynchronously when writing to disk)

From the use of SDWebImage on Github, it can be seen that SDWebImage is very recognized in the processing of image download and cache. In this paper, we mainly analyze the realization mechanism of SDWebImage from the perspective of source code. The discussion will focus on image downloading and caching, not supporting GIF and WebP images.

A, download

In SDWebImage, the image download is done by the SDWebImageDownloader class. It is an asynchronous downloader and optimized for image loading. Let’s take a look at the implementation.

1. Download options

During the download process, the application will perform different actions according to the different download options set. Download option is defined by the enumeration SDWebImageDownloaderOptions, specific as follows

  • View Code

As you can see, these options are mainly related to download priority, caching, background task execution, cookie processing for authentication.

2. Download order

The download operation of SDWebImage is handled in a certain order, which defines two download sequences, as shown below

Typedef NS_ENUM (NSInteger, SDWebImageDownloaderExecutionOrder) {/ / in the queue, in accordance with the first-in, first-out sequence of download. This is the default download order SDWebImageDownloaderFIFOExecutionOrder, / / in the stack, in accordance with the order of the lifo download. (implementation) in the form of add operation rely on SDWebImageDownloaderLIFOExecutionOrder

};

3. Download manager

The SDWebImageDownloader download manager is a singleton class that manages image download operations. The image download is done in an NSOperationQueue, declared as follows:

@property (strong, nonatomic) NSOperationQueue*downloadQueue;

By default, the maximum number of concurrent requests in a queue is 6. If necessary, we can modify this by using the maxConcurrentDownloads property of the SDWebImageDownloader class.

Serialization of network responses for all download operations is processed in a custom parallel scheduling queue, which is declared and defined as follows:

  • View Code

Each image download corresponds to some callback operations, such as download progress callback, download completion callback, etc. These callback operations are presented in the form of blocks, for which sdWebImageDownloader. h defines several blocks, as shown below:

/ / download progress typedefvoid (^ SDWebImageDownloaderProgressBlock) (NSInteger receivedSize, NSInteger expectedSize); / / the download is complete typedefvoid (^ SDWebImageDownloaderCompletedBlock) (UIImage * image, NSData * data, NSError * error, BOOL finished); / / the Header filtering typedef NSDictionary * (^ SDWebImageDownloaderHeadersFilterBlock) (NSURL * url, headers NSDictionary *);

The callbacks for image downloads are stored in the URLCallbacks property of the SDWebImageDownloader class, which is a dictionary where key is the URL of the image and value is an array containing multiple sets of callbacks for each image. Since we allow multiple images to be downloaded at the same time, it is possible for multiple threads to operate on the URLCallbacks property at the same time. To ensure thread-safe URLCallbacks (add/remove) operations, SDWebImageDownloader places these operations in the barrierQueue queue as individual tasks, and sets barriers to ensure that only one thread operates on URLCallbacks at a time. Take the add operation as an example, as shown in the following code:

  • View Code

The download manager to download the request of management are in downloadImageWithURL: options: progress: completed: method to process the inside, Calls the method mentioned above addProgressCallback: andCompletedBlock: forURL: createCallback: method to the requested information in the manager, at the same time create a callback to create a new operation in the block, Once configured, it is placed in the downloadQueue action queue, and the final method returns the newly created action. Its concrete implementation is as follows:

  • View Code

In addition, the timeout period for each download operation can be set using the downloadTimeout property, which defaults to 15 seconds.

4. Download operation

Each image download is an Operation. We examined the creation and queueing of this operation above. Now let’s look at the concrete implementation of a single operation.

SDWebImage defines a protocol, namely SDWebImageOperation, as the basic protocol for image download operations. It simply declares a cancel method to cancel the operation. The agreement states as follows:

@protocol SDWebImageOperation

  • (void)cancel;

@end

SDWebImage custom a class Operation, namely SDWebImageDownloaderOperation, it inherits from NSOperation, and adopted the SDWebImageOperation agreement. In addition to the inherited methods, the class only outward exposes a method, namely the initialization method used above initWithRequest: options: progress: completed: cancelled:.

For download images, SDWebImageDownloaderOperation depends entirely on the URL loading system the NSURLConnection class NSURLSession class after 7.0 (not use). Let’s analyze SDWebImageDownloaderOperation class for download pictures of actual data processing, namely the NSURLConnection method the implementation of each agent.

First of all, SDWebImageDownloaderOperation NSURLConnectionDataDelegate protocol is adopted in the classification, and realizes the agreement of the following methods:

  • connection:didReceiveResponse:- connection:didReceiveData:- connectionDidFinishLoading:- connection:didFailWithError:- connection:willCacheResponse:- connectionShouldUseCredentialStorage:- connection:willSendRequestForAuthenticationChallenge:

We here don’t analyze the realization of each method, the key analysis – the connection: didReceiveData: method. The main task of this method is to receive data. Each time data is received, a CGImageSourceRef object is created with the existing data for processing. When the data is obtained for the first time (width+height==0), the length, width, direction and other information of the image will be taken out from the data containing the image information for use. Then, before the image is downloaded, a CGImageSourceRef object is used to create an image object. After scaling and decompressing, a UIImage object is generated for callback. Of course, there is progress information to deal with in this method. The progress callback is called to handle the downloading progress of the current image, if we have one.

Note: For scaling, see the SDScaledImageForKey function in SDWebImageCompat. For decompression, see SDWebImageDecoder file +decodedImageWithImage

  • View Code

We said SDWebImageDownloaderOperation in front of the class is inherited from NSOperation class. Instead of simply implementing the main method, it uses the more flexible Start method to manage the download status itself.

In the start method, we create the NSURLConnection object that we will use for the download, start the image download, and throw a notification of the start of the download. Of course, if we want to download in the background processing, then only need to configure our download options, to include SDWebImageDownloaderContinueInBackground options. The start method is implemented as follows:

  • View Code

Of course, after the download completes or fails, you need to stop the run loop of the current thread, clear the connection, and throw a notification that the download has stopped. If the download is successful, the complete image data is processed, scaled and uncompressed appropriately for use in the completion callback. Specific reference – the connectionDidFinishLoading: with – connection: didFailWithError: implementation.

5, summary

The core of the download is to use the NSURLConnection object to load the data. Each image is downloaded by an Operation and placed in an action queue. This enables concurrent downloading of images.

Second, the cache

In order to reduce the consumption of network traffic, we all want to cache the downloaded images locally so that the next time we want to obtain the same image, we can directly obtain it from the local server instead of the remote server. Another benefit of this is that the user experience is improved. When the user views the same image a second time, the image can be quickly obtained locally and presented directly to the user.

SDWebImage provides support for image caching, which is done by the SDImageCache class. This class handles the memory cache and an optional disk cache. Write operations to the disk cache are asynchronous so that UI operations are not affected.

1. Memory cache and disk cache

Memory caching is handled using NSCache objects. NSCache is a container similar to a collection. It stores key-value pairs, similar to the NSDictionary class. We often use caches to temporarily store short-lived but expensive objects. Reusing these objects optimizes performance because their values do not need to be recalculated. On the other hand, these objects are not critical to the program and are discarded when memory is tight.

Disk caching is handled using NSFileManager objects. The image is stored in the Cache folder. In addition, SDImageCache defines a serial queue to store images asynchronously.

Memory cache and disk cache variables are declared and defined as follows:

  • View Code

SDImageCache provides a number of methods to cache, retrieve, remove, and empty images. For each image, we need a key value to index it in order to easily do this in memory or on disk. In memory, we use this as the key value for NSCache, and on disk, we use this key as the file name for the image. For images downloaded from a remote server, the URL is the best choice for this key. We will see the importance of this key value later.

2. Store images

Let’s start by looking at the image cache operation, which places a cache in memory, and if it is determined that it needs to be cached to disk, the disk cache operation is processed as a task in a serial queue. In iOS, the image is first detected as PNG or JPEG and converted to the corresponding image data. Finally, the data is written to disk (the file name is the string after the MD5 digest of the key value). Cache operation method is the basis of – storeImage: recalculateFromImage: imageData: forKey: toDisk and its specific implementation is as follows:

  • View Code

3, query pictures

If we want to query memory or disk for the image specified by key, we can use the following methods respectively:

  • (UIImage*)imageFromMemoryCacheForKey:(NSString*)key; – (UIImage*)imageFromDiskCacheForKey:(NSString*)key;

If you just want to see if the image specified by key exists locally, either in memory or on disk, you can use the following methods:

  • View Code

4. Remove the image

The following methods can be used to remove images:

  • (void)removeImageForKey:(NSString *)key; – (void)removeImageForKey:(NSString *)keywithCompletion:(SDWebImageNoParamsBlock)completion; – (void)removeImageForKey:(NSString *)keyfromDisk:(BOOL)fromDisk; – (void)removeImageForKey:(NSString *)keyfromDisk:(BOOL)fromDiskwithCompletion:(SDWebImageNoParamsBlock)completion;

We can choose to remove images from memory and disk simultaneously.

5. Clean up pictures (disk)

Disk cache image cleaning operations can be divided into full cleaning and partial cleaning. The complete clearing operation is to remove the cached folder directly. The clearing operation has the following two methods:

  • (void)clearDisk; – (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;

Partial cleanup is to remove some files according to some parameter values set by us. There are two main indicators: the cache validity period of files and the maximum cache space size. The cache validity of a file can be set using the maxCacheAge property, which defaults to 1 week. If the file is cached longer than this value, it is removed. The maximum cache size is set by the maxCacheSize property. If the total size of all cached files exceeds this size, the premature files will be removed half at a time in reverse order of the last modification time of the files until the actual cache size is less than the maximum we set. Cleaning operation in – cleanDiskWithCompletionBlock: method, its implementation is as follows:

  • View Code

6, summary

The above analysis of image caching operations, of course, in addition to the operations described above, the SDImageCache class provides some helper methods. For example, obtain the cache size, the number of pictures in the cache, and determine whether there is a picture specified by a key in the cache. In addition, the SDImageCache class provides an implementation of a singleton method, so we can treat it as a singleton object.

Summary of some common interfaces and attributes:

(1) -getSize: Get the disk cache size

(2) -getDiskCount: get the number of images cached on the disk

(3) -clearMemory: Clear all memory images

(4) -removeImageForKey :(NSString *) Key series of methods: remove images from memory, hard disk specified as required

(5) maxMemoryCost: the sum of pixels stored in memory

(6) maxCacheSize: Maximum cache size is in bytes. There is no default setting, which is 0, and the prerequisite for cleaning the disk cache is self.maxCacheSize > 0, so 0 means unlimited.

(7) maxCacheAge: The maximum time to be retained in memory is in seconds. The default value is one week

Third, SDWebImageManager

In practice, we do not directly use SDWebImageDownloader and SDImageCache to download and cache images. For the convenience of users, SDWebImage provides SDWebImageManager object to manage image download and cache. And we often use such as UIImageView+WebCache control classification is based on SDWebImageManager object. This object binds a downloader to an image cache and provides two read-only properties to retrieve them, as shown in the following code:

@interface SDWebImageManager : NSObject@property (weak, nonatomic) id delegate; @property (strong, nonatomic, readonly) SDImageCacheimageCache; @property (strong, nonatomic, readonly) SDWebImageDownloaderimageDownloader; . @end

We can also see from the code above that there is a delegate property, which is an ID object. SDWebImageManagerDelegate declares the two alternative implementation method, as shown below:

// Control if the image is not found in the cache, Should download which image – (BOOL) imageManager: (SDWebImageManager *) imageManager shouldDownloadImageForURL (imageURL NSURL *); // Allows images to be converted immediately before they have been downloaded and cached to disk or memory

  • (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL;

These two proxy method in SDWebImageManager – downloadImageWithURL: options: progress: completed: method calls, and this method is the core of the SDWebImageManager class. Let’s look at the implementation:

  • View Code

We haven’t explained much about this method. The main idea is to download images and cache them according to the action options. This download method of operation option parameters are defined by the enumeration SDWebImageOptions this operation with the option of SDWebImageDownloaderOptions are some of the options of the corresponding. Let’s take a look at the SDWebImageOptions options:

  • View Code

Everybody was watching – downloadImageWithURL: options: progress: completed:, you can see how the option in the two SDWebImageOptions and SDWebImageDownloaderOptions corresponding, I won’t explain much here.

Several methods of SDWebImageManager

(1) – (void)cancelAll: Cancels all operations in runningOperations and deletes all operations

(2) – (BOOL)isRunning: check whether any operation isRunning, here operation refers to the combination of download and cache operation

(3) – downloadImageWithURL: options: progress: completed: core method

(4) – (BOOL)diskImageExistsForURL:(NSURL *) URL: Specifies whether the image of the URL is cached on the disk

View extension

What I use most when I use SDWebImage are UIImageView+WebCache extensions for UIImageView that integrate UIImageView with WebCache, To give UIImageView objects the ability to asynchronously download and cache remote images. Method is one of the most core – sd_setImageWithURL: placeholderImage: options: progress: completed:, its use SDWebImageManager singleton download and cache images, When done, assign the image to the image property of the UIImageView object to display the image as follows:

  • View Code

In addition to extending UIImageView, SDWebImage also extends UIView, UIButton, MKAnnotationView and other view classes, you can refer to the source code.

Of course, if you don’t want to use these extensions, you can use the SDWebImageManager to download images directly, which is fine.

Five, technical points

The main task of SDWebImage is to download and cache images. To support these operations, it mainly uses the following knowledge points:

Dispatch_barrier_sync function: This method is used to set the order of operations to ensure that subsequent operations are performed only after the task is completed. This method is often used to ensure thread-safe operations for classes.

NSMutableURLRequest: Used to create a network request object. We can configure the request headers and other information as needed.

NSOperation and NSOperationQueue: Operation queues are advanced concurrent processing methods in Objective-C that are now implemented based on GCD. The advantage of action queues over GCD is that you can cancel tasks in the task processing queue, and it is easier to manage dependencies between operations. In SDWebImage we saw how to use dependencies to set the download order to lifO.

NSURLConnection: Used for network request and response processing. After iOS7.0, apple introduced a new set of web request interfaces, the NSURLSession class.

Start a background task.

NSCache class: a container similar to a collection. It stores key-value pairs, similar to the NSDictionary class. We often use caches to temporarily store short-lived but expensive objects. Reusing these objects optimizes performance because their values do not need to be recalculated. On the other hand, these objects are not critical to the program and are discarded when memory is tight.

Policies for clearing cached images: in particular, setting the maximum cache size. If the total size of all cached files exceeds this size, the premature files are removed recursively half at a time, in reverse order of the last modification time of the files, until the actual size of the cache is less than the maximum size we set.

Image decompression operation: this operation can be seen in sdWebImageDecoder. m +decodedImageWithImage method implementation.

Processing of GIF images

Processing of WebP pictures

Original address:

Blog.csdn.net/h22111/arti…

www.cnblogs.com/cleven/p/54…