iOS DeveloperiOS

进击的SDWebImage(一)

2016-06-07  本文已影响110人  南南小生

前言

网上有很多SDWebImage的源码分析贴,现想自己开一篇写上自己学习的点点滴滴,希望激励自己的技术能更进一步.

开篇

做为第一篇当然是弄清楚这个工具要做的是什么,那对于我们程序员来说就是一种面对过程的理解方法,那么这个第一篇就用面对过程的方法写出自己的理解.

不多说了直接上图:

//1.内存中去寻找有没有这个图
        //如果有就直接显示出来
        //2.内存中没有这个图就到磁盘中去找
                //磁盘中找到了就缓存到内存当中,并显示出来
                //3.都没找到去网络上下载
                      //如果下载成功,保存到内存和磁盘当中
                      //显示图片

先准备一点东西,写一个继承自NSCache的自己的内存缓存单例类:

+(LYCache*)sharedCache{
    static dispatch_once_t once;
    static id instance;
    dispatch_once(&once, ^{
        instance = [self new];
    });
    return instance;
}

另一个是MD5加密的方法,这个方法可以直接SDWebImage拿过来(估计还可以拿很多的工具0.0),存储图片的名字都是通过MD5加密之后存起来的,可能是这样看上去会比较舒服一点:

- (NSString *)cachedFileNameForKey:(NSString *)key {
    const char *str = [key UTF8String];
    if (str == NULL) {
        str = "";
    }
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), r);
    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[10],
                          r[11], r[12], r[13], r[14], r[15], [[key pathExtension] isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", [key pathExtension]]];
    
    return filename;
}

下面就可以去填满上面的空缺了:

    self.imageUrl = @"http://img12.360buyimg.com/n0/jfs/t289/30/1219748821/432500/b67cb240/543394bcN0cd63cef.jpg";
    NSString *key = [self cachedFileNameForKey:self.imageUrl];
    
    //1.内存中去寻找有没有这个图,这个查询应该是异步的,后面封装的时候再处理
    LYCache *cache = [LYCache sharedCache];
    UIImage *image =  [cache objectForKey:key];
    if (image) {
        self.imageView.image = image;
    }else{
        //2.内存中没有这个图就到磁盘中去找
        //磁盘中找到了缓存到内存当中
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray*path =NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
        
        NSString*documentPath = [path lastObject];
        NSString *cachePath = [NSString stringWithFormat:@"%@/myCache",documentPath];
        cachePath =  [cachePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",key]];
        BOOL isOne =  [fileManager fileExistsAtPath:cachePath];
        if (isOne) {
            
            //保存到内存当中
            LYCache *cache = [LYCache sharedCache];
            [cache setObject:image forKey:key];
            
            UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfFile:cachePath]];
            self.imageView.image = image;
        }else{
            //3.都没找到去网络上下载
            //开启下载
            NSURLSessionConfiguration *sessionConfig =[NSURLSessionConfiguration defaultSessionConfiguration];
            
            NSURLSession *session =[NSURLSession sessionWithConfiguration:sessionConfig
                                                                 delegate:self
                                                            delegateQueue:nil];
            
            NSURLSessionDownloadTask *getImageTask = [session downloadTaskWithURL:[NSURL URLWithString:self.imageUrl]];
            
            [getImageTask resume];
        }
    }

下载的代理方法:

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
    
    NSData *imageData = [NSData dataWithContentsOfURL:location];
    if (imageData) {
        UIImage *downloadImage = [UIImage imageWithData:imageData];
        
        //保存到内存当中
        LYCache *cache = [LYCache sharedCache];
        NSString *key = [self cachedFileNameForKey:self.imageUrl];
        [cache setObject:downloadImage forKey:key];
        
        //保存到磁盘当中
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray*path =NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
        
        NSString*documentPath = [path lastObject];
        NSString *cachePath = [NSString stringWithFormat:@"%@/myCache",documentPath];
        //如果没有这文件夹就创建文件夹
        if (![fileManager fileExistsAtPath:cachePath]) {
            [fileManager createDirectoryAtPath:cachePath  withIntermediateDirectories:YES attributes:nil error:nil];
        }
        
        cachePath =  [cachePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",key]];
        
        BOOL isSuccess = [fileManager createFileAtPath:cachePath contents:imageData attributes:nil];
        if (isSuccess) {
            NSLog(@"存储成功");
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = downloadImage;
            });
        }else{
            NSLog(@"存储失败");
        }
    }
}

总结:

自己一写才知道要很完美估计是不能的,但是一边看SDWebImage的源码才看出自己的很多的不足,后面的章节要开始封装了,还是对照的SDWebImage来一点点写下去,希望能从中学到更多的东西(面对对象的思想,架构的思想,一些奇特的用法等等),也希望大家多给意见.

上一篇下一篇

猜你喜欢

热点阅读