Caching mechanism of Sdwebimage

Source: Internet
Author: User
Tags transparent color

Access Delete Path

1.1 Save

Is in Storeimage this method:

Save pictures to memory and hard disk

-(void) Storeimage: (UIImage *) Image recalculatefromimage: (BOOL) Recalculate ImageData: (NSData *) ImageData Forkey: (NSString *) Key Todisk: (BOOL) Todisk {if (!image | |!key) {return;}If memory cache is enabledif (Self.shouldcacheimagesinmemory) {Nsuinteger cost = sdcachecostforimage (image); [Self.memcache setobject:image Forkey:key cost:cost];}if (Todisk) {Dispatch_async (Self.ioqueue, ^{NSData *data = ImageData;If the image exists but needs to be recalculated (recalculate) or data is emptyThe new data will be regenerated based on the image.But if even the image is empty, then don't save it.if (Image && (Recalculate | |!data)) {#if Target_os_iphoneWe need to determine if the image is PNG or JPEGPNG images are easy to detect because they have a specific mark (http://www.w3.org/TR/PNG-Structure.html)The first 8 bytes of a PNG image are not allowed to match the following values (in decimal notation)137 80 78 71 13 10 26 10If ImageData is empty l (for example, if image needs transform after download, then ImageData will be empty)And the image has an alpha channel, we see the image as PNG to avoid the loss of transparency (Alpha) (because JPEG has no transparent color)int alphainfo =Cgimagegetalphainfo (image. Cgimage);Gets the transparency information in the imageThe image does have transparent information, which is considered to be PNGBOOL Hasalpha =! (Alphainfo = = kCgimagealphanone | | Alphainfo = = kCgimagealphanoneskipfirst | | Alphainfo = = kCgimagealphanoneskiplast);BOOL imageispng = Hasalpha;But if we already have imagedata, we can determine whether PNG is directly based on the first few bytes of data.if ([imageData length] >= [kpngsignaturedata length]) {Imagedatahaspngpreffix is to determine whether the first 8 bytes of ImageData are compliant with the PNG flag imageispng = Imagedatahaspngpreffix (ImageData); }If the image is in PNG format, it is converted to nsdata with Uiimagepngrepresentation, otherwise converted in JPEG format with a compression quality of 1, i.e. no compressionif (imageispng) {data =Uiimagepngrepresentation (image); }else {data =UIImageJPEGRepresentation (Image, (CGFloat)1.0); }#elseOf course, if not on the iphone platform, use the following method. But not within our scope of study. Data = [Nsbitmapimagerep representationOfImageRepsInArray:image.representations Usingtype:Nsjpegfiletype Properties:NIL];#endif}Once you get the data that you need to store, you'll use FileManager to store it.if (data) {First determine if the file path of disk cache exists, and if it does not exist, create aThe file path of disk cache is stored in the _diskcachepathif (![ _filemanager Fileexistsatpath:_diskcachepath]) {[_filemanager Createdirectoryatpath:_diskcachepath Withintermediatedirectories:YES attributes:Nil Error:NULL]; }Combined into the final file path based on the image's key (generally understood as the URL of the image)The resulting file path above is just a file directory, just like the difference between/cache/images/img1.png and cache/images/.NSString *cachepathforkey = [Self defaultcachepathforkey:key]; //This URL is not the URL of the network side, but the URL of file in the system path //such as/foo/bar/baz--------> File:///foo/bar/baz nsurl *fileurl = [ Nsurl Fileurlwithpath:cachepathforkey]; (/ //////based on the stored path (cachepathforkey) and stored data) to the iOS file system [_filemanager Createfileatpath:cachepathforkey Contents: Data attributes:nil]; //Disable ICloud backup if (self.shoulddisableicloud) {[FileURL setresourcevalue:[NSNumber Numberwithbool:YES] Forkey:nsurlisexcludedfrombackupkey Error:nil];}} });}}
1.2 Take

The memory cache uses Nscache's objectforkey to fetch data:

- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key {    return [self.memCache objectForKey:key];}

Disk fetch data constantly using Datawithcontentsoffile to test whether the data is in the path of the key

-(uiimage *) Imagefromdiskcacheforkey: (nsstring *) key {//first check the in-memory cache...uiimage *image = [self imagefrommemorycacheforkey:key]; if (image) {return image;} //Second check the disk cache ... uiimage *diskimage = [self Diskimageforkey:key];if (diskimage && self.shouldcacheimagesinmemory) {nsuinteger cost = Sdcachecostforimage (DiskImage); [self.memcache setobject:diskimage forkey:key cost:cost];} return diskimage;}           
1.3 by deleting
    1. Removeimageforkeyfromdisk:withcompletion://Asynchronously removes the image from the cache (memory cache and optional disk cache)
    2. Clearmemory//Clear all image on memory cache
    3. Cleardisk//Clears all the image on the disk cache
    4. Cleandisk//Clears the expired image on the disk cache

Look at one of the longest:

Implements a simple cache purge policy: Clears the file-of the earliest modification time (void) Cleandiskwithcompletionblock: (Sdwebimagenoparamsblock) Completionblock {Dispatch_async (Self.ioqueue, ^{These two variables are mainly for the following generation NsdirectoryenumeratorOne is the file directory traversed by the record, and one is what attributes of the record traversal need to get the file beforehandNsurl *diskcacheurl = [Nsurl Fileurlwithpath:Self.diskcachepath isdirectory:YES];Nsarray *resourcekeys = @[Nsurlisdirectorykey,Nsurlcontentmodificationdatekey,Nsurltotalfileallocatedsizekey];Recursively iterates through all the directories in the Diskcachepath folder, not directly using Diskcachepath, but using the generated NsurlThe Includingpropertiesforkeys:resourcekeys is used here so that the corresponding properties of each file's Resourcekeys are pre-acquired in the duration of theNsdirectoryenumerationskipshiddenfiles indicates that hidden files are not traversedNsdirectoryenumerator *fileenumerator = [_filemanager enumeratoraturl:diskcacheurl includingPropertiesForKeys: Resourcekeys options:Nsdirectoryenumerationskipshiddenfiles ErrorHandler:NULL];Gets the file expiration time, which is one weeks by default in SdwebimageBut although this is called *expirationdate, it is not in essence.In fact, for example, in 2015/12/12/00:00:00 last modification of the file, the corresponding expiration time should be2015/12/19/00:00:00, but now the time is 2015/12/27/00:00:00, I will first subtract the current time 1 weeks, get2015/12/20/00:00:00, this time is the expirationdate in our function.Use this expirationdate and the last modification time Modificationdate compare who looks late.NSDate *expirationdate = [NSDate datewithtimeintervalsincenow:-Self.maxcacheage];Some of the properties used to store the corresponding file, such as the disk space required for the fileNsmutabledictionary *cachefiles = [Nsmutabledictionary dictionary];Record the size of the disk cache that is currently in useNsuinteger currentcachesize =0;The cached directory begins to traverse the file. This traversal has two purposes://1. To remove an expired file2. Also stores the properties of each file (such as whether the file is a folder, the disk size required for the file, and the modified time)Nsmutablearray *urlstodelete = [[Nsmutablearray alloc] init];for (Nsurl *fileurlIn FileEnumerator) {Nsdictionary *resourcevalues = [FileURL resourcevaluesforkeys:resourcekeys error:NULL];The current scan is a directory, skipif ([resourcevalues[Nsurlisdirectorykey] Boolvalue]) {Continue }Remove outdated filesHere's how to determine the expiration: Compare the file's last modified date and expirationdate who is later, if ExpirationDate later, think that the file has expired, specifically explained aboveNSDate *modificationdate = resourcevalues[Nsurlcontentmodificationdatekey];if ([[[Modificationdate Laterdate:expirationdate] isequaltodate:expirationdate]) {[Urlstodelete AddObject:fileURL];Continue }Calculates the cache size that is currently in use,and save the properties of the corresponding file in the CachefilesNSNumber *totalallocatedsize = resourcevalues[Nsurltotalfileallocatedsizekey]; Currentcachesize + = [totalallocatedsize unsignedintegervalue]; [Cachefiles setobject:resourcevalues Forkey:fileurl]; }for (Nsurl *fileurlIn Urlstodelete) {Remove the corresponding file [_filemanager removeitematurl:fileurl error by removing the URL of the document as needed:NIL]; }If our current cache size has exceeded the allowable cache size, delete the cached files.Deleting a policy is to first delete the cache file with the earlier modified timeif (Self.maxcachesize >0 && currentcachesize >Self.maxcachesize) {Drop the current cache size directly to the maximum allowable cache sizeConstNsuinteger desiredcachesize =Self.maxcachesize/2;Sort all cache files according to the file modification time, sort the previous rule by the earlier the modification timeNsarray *sortedfiles = [Cachefiles keyssortedbyvaluewithoptions:Nssortconcurrent usingcomparator:^Nscomparisonresult (ID obj1,ID obj2) {return [obj1[Nsurlcontentmodificationdatekey] compare:obj2[Nsurlcontentmodificationdatekey]]; }];Each time you delete file, the size of the cache at this time is calculatedIf the cache size has dropped to the desired size at this point, stop deleting the file.for (Nsurl *fileurlin sortedfiles) {if ([_filemanager removeitematurl:fileurl error:nil]) { Span class= "Hljs-comment" >//gets the property corresponding to the file nsdictionary *resourcevalues = cachefiles[ FileURL]; //the amount of disk space required for the file according to Resourcevalues nsnumber * Totalallocatedsize = Resourcevalues[nsurltotalfileallocatedsizekey]; //calculates the current cache size currentcachesize-= [Totalallocatedsize unsignedintegervalue]; if (Currentcachesize < desiredcachesize) {break;}} } //if there is Completionblock, call if (Completionblock) in the main thread {dispatch_async (Dispatch_get_main_queue (), ^{Completionblock ();}); }});}
1.4 Image Storage Path
Simple encapsulation of the cachepathforkey:inpath-(NSString *) Defaultcachepathforkey: (NSString *) Key {return [Self Cachepathforkey:key inpath:Self.diskcachepath];}cachepathforkey:inpath-(NSString *) Cachepathforkey: (NSString *) Key Inpath: (NSString *) Path {Creates the file name to be stored, based on the key passed inNSString *filename = [Self Cachedfilenameforkey:key];Binds the stored file path and the file name together as the final storage pathreturn [path Stringbyappendingpathcomponent:filename];}cachedfilenameforkey:-(NSString *) Cachedfilenameforkey: (NSString *) Key {Constchar *str = [key utf8string];if (str = =NULL) {str ="";}Using MD5 for cryptographic processingOpen up a space of 16 bytes (128 bits: MD5 encrypted out is 128bit)UnsignedChar R[cc_md5_digest_length];The official package is good encryption methodThe STR string is converted into a 32-bit 16-digit sequence (the process is irreversible) stored in the R space Cc_md5 (str, (Cc_long) strlen (str), R);The resulting file name is "MD5 code" + ". File Type"NSString *filename = [NSString stringWithFormat:@ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@", r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9],r[], r[11], R[],r[], r[],r[[[Key Pathextension] isequaltostring:@ ""]? @ "": [nsstring stringWithFormat:@ ".%@", [key pathextension]];  return filename;}                  

Caching mechanism of Sdwebimage

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.