SDWebImage前世今生之V2.3版本

2019-03-07  本文已影响0人  _相信自己_

2.3版本2010年9月17日发布

1. SDImageCacheDelegate 新增该代理类

//-------------------2.3版本更新-缓存回调-------------------
@class SDImageCache;
@protocol SDImageCacheDelegate <NSObject>
@optional
//缓存过程中有图片,缓存成功
- (void)imageCache:(SDImageCache *)imageCache didFindImage:(UIImage *)image forKey:(NSString *)key userInfo:(NSDictionary *)info;
//缓存过程中没有图片,缓存失败了
- (void)imageCache:(SDImageCache *)imageCache didNotFindImageForKey:(NSString *)key userInfo:(NSDictionary *)info;
@end
//---------------------------end-------------------------

2. UIImageView + WebCache 抽象缓存逻辑到管理器中

//-------------------2.3版本更新-优化处理-------------------
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder{
    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    [manager cancelForDelegate:self];
    self.image = placeholder;
    if (url){
        [manager downloadWithURL:url delegate:self];
    }
}
//---------------------------end-------------------------

3. SDWebImageManager 实现SDImageCacheDelegate协议

        缓存代理,异步检查磁盘上的缓存,这样我们就不会阻塞主线程缓存代理回调实现。
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate{
    if (!url || !delegate || [failedURLs containsObject:url]){
        return;
    }
    //-------------------2.3版本更新-避免阻塞主线程-------------------
    //检查磁盘上的缓存异步,这样我们就不会阻塞主线程
    NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", nil];
    [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info];
    //---------------------------end-------------------------
}

//--------------------2.3版本更新--实现协议SDImageCacheDelegate功能----------
- (void)imageCache:(SDImageCache *)imageCache didFindImage:(UIImage *)image forKey:(NSString *)key userInfo:(NSDictionary *)info{
    id<SDWebImageManagerDelegate> delegate = [info objectForKey:@"delegate"];
    if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:)]){
        [delegate performSelector:@selector(webImageManager:didFinishWithImage:) withObject:self withObject:image];
    }
}

- (void)imageCache:(SDImageCache *)imageCache didNotFindImageForKey:(NSString *)key userInfo:(NSDictionary *)info{
    NSURL *url = [info objectForKey:@"url"];
    id<SDWebImageManagerDelegate> delegate = [info objectForKey:@"delegate"];
    //为相同的URL共享相同的下载加载程序,所以我们不会多次下载相同的URL
    SDWebImageDownloader *downloader = [downloaderForURL objectForKey:url];
    if (!downloader){
        downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];
        [downloaderForURL setObject:downloader forKey:url];
    }
    [delegates addObject:delegate];
    [downloaders addObject:downloader];
}
//------------------------------------end---------------------------------

4. SDImageCache

@interface SDImageCache : NSObject{
    NSMutableDictionary *memCache;
    NSString *diskCachePath;
    NSOperationQueue *cacheInQueue;
    
    //-------------------2.3版本更新-避免阻塞主线程--------------------
    NSOperationQueue *cacheOutQueue;
    //--------------------------------end--------------------------
}

- (UIImage *)imageFromKey:(NSString *)key;
- (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk;

//---------------2.3版本更新-新增功能->异步方法--------------------
- (void)queryDiskCacheForKey:(NSString *)key delegate:(id<SDImageCacheDelegate>)delegate userInfo:(NSDictionary *)info;
//-------------------------------end---------------------------
@end
//---------------2.3版本更新-新增功能->异步方法--------------------
- (void)notifyDelegate:(NSDictionary *)arguments{
    NSString *key = [arguments objectForKey:@"key"];
    id <SDImageCacheDelegate> delegate = [arguments objectForKey:@"delegate"];
    NSDictionary *info = [arguments objectForKey:@"userInfo"];
    UIImage *image = [arguments objectForKey:@"image"];
    if (image){
        [memCache setObject:image forKey:key];
        if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)]){
            [delegate imageCache:self didFindImage:image forKey:key userInfo:info];
        }
    } else {
        if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)]){
            [delegate imageCache:self didNotFindImageForKey:key userInfo:info];
        }
    }
}
- (void)queryDiskCacheOperation:(NSDictionary *)arguments{
    NSString *key = [arguments objectForKey:@"key"];
    NSMutableDictionary *mutableArguments = [arguments mutableCopy];
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self cachePathForKey:key]];
    if (image){
        [mutableArguments setObject:image forKey:@"image"];
    }
    [self performSelectorOnMainThread:@selector(notifyDelegate:) withObject:mutableArguments waitUntilDone:NO];
}
- (void)queryDiskCacheForKey:(NSString *)key delegate:(id <SDImageCacheDelegate>)delegate userInfo:(NSDictionary *)info{
    if (!delegate){
        return;
    }
    if (!key){
        if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)]){
            [delegate imageCache:self didNotFindImageForKey:key userInfo:info];
        }
        return;
    }
    //首先检查内存缓存…
    UIImage *image = [memCache objectForKey:key];
    if (image){
        //从缓存中读取到了图片
        //立即通知delegate,不需要去异步
        if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)]){
            [delegate imageCache:self didFindImage:image forKey:key userInfo:info];
        }
        return;
    }
    //缓存中没有
    NSMutableDictionary *arguments = [NSMutableDictionary dictionaryWithCapacity:3];
    [arguments setObject:key forKey:@"key"];
    [arguments setObject:delegate forKey:@"delegate"];
    if (info){
        [arguments setObject:info forKey:@"userInfo"];
    }
    [cacheOutQueue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(queryDiskCacheOperation:) object:arguments]];
}
//------------------------end------------------------
上一篇下一篇

猜你喜欢

热点阅读