iOS Learning Notes - 127. SDWebImage 3 - Cache Clearance and Operation Cancellation

SDWebImage 3 -- Cache Clearance and Operation Cancellation

1. Clear the cache and put it there most easily

When our app needs to display pictures on multiple controllers, we want to clear the cache ourselves if a memory warning occurs. So where should I put it?

  1. Can be placed in the controller, but many controllers are used, need to be written everywhere, feeling a little sad.

  2. Put it in AppDelegate, so we only need to write it once.

2. Cache Clearance Method

The method to clear the cache can be invoked through the imageCache object in the SDWeb Image Manager's singleton. as

[[SDWebImageManager sharedManager].imageCache clearMemory];

2.1 Clear Memory Clears Memory

To clear the memory cache, we can use the following methods

[[SDWebImageManager sharedManager].imageCache clearMemory];

So what did it do? Let's go and see.

This method in SDIMAGE Cache is as follows

//Clear memory cache
- (void)clearMemory {
    //Delete all memory caches
    [self.memCache removeAllObjects];
}

Simple and rude, delete all memory caches

2.2 CleaDisk Clear Disk

To clear the memory cache, we can use the following methods

[[SDWebImageManager sharedManager].imageCache clearMemory];

So what did it do? Let's go and see.

This method in SDIMAGE Cache is as follows

//Clear disk cache
- (void)clearDisk {
    [self clearDiskOnCompletion:nil];
}

//Clear the disk cache (simple and rude)
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion
{
    //Open Subthread Asynchronous Processing for Cleaning Disk Cache
    dispatch_async(self.ioQueue, ^{
        //Delete Cache Path
        [_fileManager removeItemAtPath:self.diskCachePath error:nil];
        //Recreate Cache Path
        [_fileManager createDirectoryAtPath:self.diskCachePath
                withIntermediateDirectories:YES
                                 attributes:nil
                                      error:NULL];

        if (completion) {
            //Processing completion callbacks in the main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                completion();
            });
        }
    });
}

The same is true for this way of clearing disks. Delete the cache folder directly, and then create an empty folder. After these operations, go to the main line to process the completion callback.

2.2 Clean Disk Clean Disk

This method of clearing disks is mainly based on two aspects.

Firstly, the documents are so obsolete that they are cleared.

Second, calculate the size of the current cache and compare it with the maximum number of caches set up. If it exceeds that, it will continue to be deleted (in the order in which the files were created).

This method in SDIMAGE Cache is as follows

//Clear out expired disk caches
- (void)cleanDisk {
    [self cleanDiskWithCompletionBlock:nil];
}

//Clear out expired disk caches
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock {
    dispatch_async(self.ioQueue, ^{
        NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
        NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];

        // This enumerator prefetches useful properties for our cache files.
        NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
                                                   includingPropertiesForKeys:resourceKeys
                                                                      options:NSDirectoryEnumerationSkipsHiddenFiles
                                                                 errorHandler:NULL];

        // Calculate expiration date
        NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
        NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary];
        NSUInteger currentCacheSize = 0;

        // Enumerate all of the files in the cache directory.  This loop has two purposes:
        //
        //  1. Removing files that are older than the expiration date.
        //  2. Storing file attributes for the size-based cleanup pass.
        // Traversing through all files in the cache path, this loop achieves two purposes
        //  1. Delete files earlier than expiration date
        //  2. Save file attributes to calculate disk cache footprint
        NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init];
        for (NSURL *fileURL in fileEnumerator) {
            NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];

            // Skip directories.
            // Skip directory
            if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
                continue;
            }

            // Remove files that are older than the expiration date;
            // Record expired files to be deleted

            NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey];
            if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) {
                [urlsToDelete addObject:fileURL];
                continue;
            }

            // Store a reference to this file and account for its total size.
            //Save file references to calculate total size
            NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
            currentCacheSize += [totalAllocatedSize unsignedIntegerValue];
            [cacheFiles setObject:resourceValues forKey:fileURL];
        }

        // Delete expired files
        for (NSURL *fileURL in urlsToDelete) {
            [_fileManager removeItemAtURL:fileURL error:nil];
        }

        // If our remaining disk cache exceeds a configured maximum size, perform a second
        // size-based cleanup pass.  We delete the oldest files first.
        //If the remaining disk cache space exceeds the maximum, clean up again and delete the earliest files
        if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) {
            // Target half of our maximum cache size for this cleanup pass.
            const NSUInteger desiredCacheSize = self.maxCacheSize / 2;

            // Sort the remaining cache files by their last modification time (oldest first).
            NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
                                                            usingComparator:^NSComparisonResult(id obj1, id obj2) {
                                                                return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
                                                            }];

            // Delete files until we fall below our desired cache size.
            // Remove files in turn until they are below the expected cache limit
            for (NSURL *fileURL in sortedFiles) {
                if ([_fileManager removeItemAtURL:fileURL error:nil]) {
                    NSDictionary *resourceValues = cacheFiles[fileURL];
                    NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
                    currentCacheSize -= [totalAllocatedSize unsignedIntegerValue];

                    if (currentCacheSize < desiredCacheSize) {
                        break;
                    }
                }
            }
        }
        //Processing complete callbacks in the main thread
        if (completionBlock) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completionBlock();
            });
        }
    });
}

2.4 Maximum Cache Time

We mentioned the maximum cache time above, so what is its value?

This default value is defined in the following method of SDImageCache


// Instantiate a new cache store and directory using the specified namespace
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory {
......
// Initialize the default maximum cache time = 1 week
_maxCacheAge = kDefaultCacheMaxCacheAge;
......
}

Let's look at kDefault Cache Max CacheAge again.


// The default maximum cache time is 1 week
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week

So the default maximum cache time is one week.

### 2.5 Maximum Cache Size

As we know above, besides the time, the size of the cache is also the basis for judging when cleaning Disk is used. So let's take a look at the largest cache size.


/**
* The maximum size of the cache, in bytes.
*
* The total size of the cached image, in bytes, is 0 by default, indicating no restriction.
*/
@property (assign, nonatomic) NSUInteger maxCacheSize;

III. Cancellation

//Cancel all current operations
[[SDWebImageManager sharedManager] cancelAll];

IV. Sample Code

//
//  AppDelegate.m
//  03_UIview87_SDWebImage
//
//  Created by Qi Civilization on 17/9/7.
//  Copyright 2017 Qi Civilization. All rights reserved.
//

#import "AppDelegate.h"
#import "SDWebImageManager.h"
@interface AppDelegate ()

@end

@implementation AppDelegate

-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
    //1. Empty the cache
    //clear: Delete the files under the cache directory directly and recreate the empty cache files
    //clean: clean out expired caches, calculate the size of the current cache, and compare it with the maximum number of caches set. If it exceeds that, it will continue to be deleted (in the order in which the files were created)
    //Overdue time: 7 days
    [[SDWebImageManager sharedManager].imageCache cleanDisk];
//    [[SDWebImageManager sharedManager].imageCache clearMemory];

    //2. Cancel all current operations
    [[SDWebImageManager sharedManager] cancelAll];
}

@end

Posted by mike760534211 on Sun, 26 May 2019 15:05:43 -0700