SDWebImage源代码梳理2#分离各个类的职责

在BJCAImageCache.h文件中做了如下修改:

@interface BJCAImageCache : NSObject

{
    NSMutableDictionary *memache;
    NSString *diskCachePath;
    NSOperationQueue *cacheInQueue;
}

在BJCAImageCache.m文件中做的修改:

-(instancetype)init
{
	cacheInQueue = [[NSOperationQueue alloc] init];
  cacheInQueue.maxConcurrentOperationCount = 2;
}

主要的修改是在缓存到磁盘的时候,用了如下:

NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(storeKeyToDisk:) object:key];
[cacheInQueue addOperation:invocationOperation];

-(void)storeKeyToDisk:(NSString *)key
{
    UIImage *image = [self imageFromKey:key fromDisk:YES];
    if (image != nil)
    {
        /**
         iOS中有两种转化图片的简单方法:
         1、UIImageJPEGRepresentation 图片、压缩系数。
         压缩后图片较小,图片质量也无较大差异,日常中主要用这个方法
         2、UIImagePNGRepresentation 图片
         压缩图片的图片较大
         */
        [[NSFileManager defaultManager] createFileAtPath:[self cachePathForKey:key] contents:UIImageJPEGRepresentation(image, 1.0) attributes:nil];
    }
}

记得在清理内存和磁盘的时候,把队列里面的操作停止掉:

[cacheInQueue cancelAllOperations];

将BJCAWebImageDownloader类单独拿了出去

//BJCAWebImageDownloader.h文件
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface BJCAWebImageDownloader : NSOperation

{
    NSURL *url;
    id target;
    SEL action;
}

@property (nonatomic, strong) NSURL *url;
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL action;

+(id)downloaderWithURL:(NSURL *)url target:(id)target action:(SEL)action;
+(void)setMaxConcurrentDownloads:(NSUInteger)max;

@end

NS_ASSUME_NONNULL_END
//BJCAWebImageDownloader.m文件
#import "BJCAWebImageDownloader.h"
#import <UIKit/UIKit.h>
#import "BJCAImageCache.h"

static NSOperationQueue *queue;

@implementation BJCAWebImageDownloader

@synthesize url, target, action;

+(id)downloaderWithURL:(NSURL *)url target:(id)target action:(SEL)action
{
    BJCAWebImageDownloader *downloader = [[BJCAWebImageDownloader alloc] init];
    downloader.url = url;
    downloader.target = target;
    downloader.action = action;
    
    if (queue == nil)
    {
        queue = [[NSOperationQueue alloc] init];
        queue.maxConcurrentOperationCount = 8;
    }
    [queue addOperation:downloader];
    return downloader;
}

+(void)setMaxConcurrentDownloads:(NSUInteger)max
{
    if (queue == nil)
    {
        queue = [[NSOperationQueue alloc] init];
    }
    queue.maxConcurrentOperationCount = max;
}

-(void)main
{
    @autoreleasepool
    {
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        if (!self.isCancelled)
        {
            [target performSelector:@selector(action) withObject:image];
        }
        [[BJCAImageCache sharedImageCache] storeImage:image forKey:[url absoluteString]];
    }
}

@end
//BJCAWebImageView.m文件
#import "BJCAWebImageView.h"
#import "BJCAImageCache.h"
#import "BJCAWebImageDownloader.h"

@implementation BJCAWebImageView

#pragma mark RemoteImageView
-(void)setImageWithURL:(NSURL *)url
{
    if (currentOperation != nil)
    {
        [currentOperation cancel];//从队列中删除
        currentOperation = nil;
    }
    //保存占位图图像,以便在视图被重用的时候重新应用占位图
    if (placeHolderImage == nil)
    {
        placeHolderImage = self.image;
    }
    else
    {
        self.image = placeHolderImage;
    }
    //完整的url字符串当做key
    UIImage *cachedImage = [[BJCAImageCache sharedImageCache] imageFromKey:[url absoluteString]];
    if (cachedImage)
    {
        self.image = cachedImage;
    }
    else
    {
        currentOperation = [BJCAWebImageDownloader downloaderWithURL:url target:self action:@selector(downloadFinishedWithImage:)];
    }
}

-(void)downloadFinishedWithImage:(UIImage *)image
{
    self.image = image;
    currentOperation = nil;
}

@end

这次的改动就是减少了BJCAWebImageView的代码量,将缓存的内容都放到了BJCAImageCache中,将下载的内容都放到了BJCAWebImageDownloader中。

demo在以下地址和提交点:

https://github.com/DYS12345/SDWebImage-/tree/dev

88055a56e8d9852f1d5212baec449e80e9f87c44

猜你喜欢

转载自blog.csdn.net/run_in_road/article/details/113848654