SDWebImage前世今生之V2.4版本

2.4版本2011年10月1日发布

1. 类结构新增了两个类

  • UIButton+WebCache 设置Button Image
//------------------------------2.4版本更新-功能扩展-------------------------
@interface UIButton (WebCache) <SDWebImageManagerDelegate>

- (void)setImageWithURL:(NSURL *)url;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
- (void)cancelCurrentImageLoad;

@end
//-----------------------------------end-----------------------------------
//------------------------------2.4版本更新-功能优化-------------------------
@implementation UIButton (WebCache)

- (void)setImageWithURL:(NSURL *)url{
    [self setImageWithURL:url placeholderImage:nil];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder{
    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    //从队列中删除正在进行中的下载加载程序
    [manager cancelForDelegate:self];
    [self setImage:placeholder forState:UIControlStateNormal];
    if (url){
        [manager downloadWithURL:url delegate:self];
    }
}

- (void)cancelCurrentImageLoad{
    [[SDWebImageManager sharedManager] cancelForDelegate:self];
}

- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image{
    //下载成功
    //正常情况下Button图片(默认情况下):UIControlStateNormal
    [self setImage:image forState:UIControlStateNormal];
}

@end
//-----------------------------------end-----------------------------------

  • SDWebImageCompat.h 系统版本兼容(设备、平台兼容)
#import <TargetConditionals.h>

//-------------------2.4版本更新-新增平台兼容-------------------
//TARGET_OS_IPHONE  //真机
//TARGET_IPHONE_SIMULATOR  //模拟器
#if !TARGET_OS_IPHONE
#import <AppKit/AppKit.h>

#ifndef UIImage
#define UIImage NSImage
#endif

#ifndef UIImageView
#define UIImageView NSImageView
#endif
#else
#import <UIKit/UIKit.h>
#endif
//----------------------------end----------------------------

2. SDWebImageManager

  • 重命名下载器代理对象集合(downloadDelegates
  • 新增缓存器代理对象集合
  • 新增重新下载功能(下载失败了)
@interface SDWebImageManager : NSObject <SDWebImageDownloaderDelegate, SDImageCacheDelegate>{
    NSMutableArray *downloaders;
    NSMutableDictionary *downloaderForURL;
    NSMutableArray *failedURLs;
    
    //-----------------------2.4版本更新-下载回调与缓存回调-----------------------
    //存储下载器代理对象(下载多张图片,存在多个代理)
    NSMutableArray *downloadDelegates;
    //存储缓存器代理对象(缓存多张图片,存在多个代理)
    NSMutableArray *cacheDelegates;
    //------------------------------------end---------------------------------
}

//-----------------------2.4版本更新-新增-重新下载方法 、低优先级回调-----------------------
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate retryFailed:(BOOL)retryFailed;
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority;
//------------------------------------end---------------------------------
@end

3. SDWebImageManagerDelegate

  • 新增didFailWithError回调
@protocol SDWebImageManagerDelegate <NSObject>
@optional
- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image;

//-----------------------2.4版本更新-错误回调-----------------------
- (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error;
//---------------------------------end------------------------------
@end

4. SDWebImageDownloader

  • 新增下载器通知(通知的方式回调)
    开始下载:SDWebImageDownloadStartNotification
    结束下载:SDWebImageDownloadStopNotification
  • 增加用户信息属性与下载优先级
    用户信息属性:userInfo(保存一些公共参数信息)
    下载优先级:lowPriority(是否重新下载)
  • 新增两个方法重载
    用户信息:
    + (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo;
    下载优先级:
    + (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority;
//-----------------------2.4版本更新-功能优化-----------------------
extern NSString *const SDWebImageDownloadStartNotification;
extern NSString *const SDWebImageDownloadStopNotification;
//-----------------------------end-------------------------------

@interface SDWebImageDownloader : NSObject{
    @private
    NSURL *url;
    NSURLConnection *connection;
    NSMutableData *imageData;
    //-----------------------2.4版本更新-功能优化-----------------------
    id userInfo;
    BOOL lowPriority;
    //-----------------------------end-------------------------------
}
@property (nonatomic, retain) NSURL *url;
@property (nonatomic, assign) id<SDWebImageDownloaderDelegate> delegate;

@property (nonatomic, retain) NSMutableData *imageData;

//-----------------------2.4版本更新-功能优化--------------
@property (nonatomic, retain) id userInfo;
@property (nonatomic, readwrite) BOOL lowPriority;
//-----------------------------end----------------------

+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate;

//-----------------------2.4版本更新-新增功能--------------
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority;
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo;
//-----------------------------end----------------------
@end
//-----------------------2.4版本更新-功能优化-----------------------
NSString *const SDWebImageDownloadStartNotification = @"SDWebImageDownloadStartNotification";
NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification";
//-----------------------------end-------------------------------

@implementation SDWebImageDownloader

//-----------------------------------2.4版本更新-新增功能----------------------------
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate{
    return [self downloaderWithURL:url delegate:delegate userInfo:nil];
}
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo{
    return [self downloaderWithURL:url delegate:delegate userInfo:userInfo lowPriority:NO];
}

+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority{
    //绑定SDNetworkActivityIndicator(下载地址:http://github.com/rs/SDNetworkActivityIndicator)
    //要使用它,除了SDWebImage的导入,只需添加#import "SDNetworkActivityIndicator
    if (NSClassFromString(@"SDNetworkActivityIndicator")){
        id activityIndicator = [NSClassFromString(@"SDNetworkActivityIndicator") performSelector:NSSelectorFromString(@"sharedActivityIndicator")];
        [[NSNotificationCenter defaultCenter] addObserver:activityIndicator
                                                 selector:NSSelectorFromString(@"startActivity")
                                                     name:SDWebImageDownloadStartNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:activityIndicator
                                                 selector:NSSelectorFromString(@"stopActivity")
                                                     name:SDWebImageDownloadStopNotification object:nil];
    }

    SDWebImageDownloader *downloader = [[SDWebImageDownloader alloc] init];
    downloader.url = url;
    downloader.delegate = delegate;
    downloader.userInfo = userInfo;
    downloader.lowPriority = lowPriority;
    [downloader performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:YES];
    return downloader;
}
//-----------------------------------------end------------------------------------

- (void)start{
    //------------------------------2.4版本更新-功能优化-------------------------
    //为了防止潜在的重复缓存(NSURLCache + SDImageCache),我们为图像请求禁用缓存
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    //如果不是低优先级模式,确保我们不会被UI操作阻塞(NSURLConnection的默认runloop模式是NSEventTrackingRunLoopMode)
    if (!lowPriority){
        [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    }
    [connection start];
    if (connection){
        self.imageData = [NSMutableData data];
        [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:nil];
    } else {
        if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)]){
            [delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:nil];
        }
    }
    //--------------------------------------end-------------------------------
}

//------------------------------2.4版本更新-功能优化-------------------------
#pragma GCC diagnostic ignored "-Wundeclared-selector"
//-----------------------------------end-----------------------------------
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection{
    self.connection = nil;
    //------------------------------2.4版本更新-功能优化-------------------------
    [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil];
    //-----------------------------------end-----------------------------------
    if ([delegate respondsToSelector:@selector(imageDownloaderDidFinish:)]){
        [delegate performSelector:@selector(imageDownloaderDidFinish:) withObject:self];
    }
    if ([delegate respondsToSelector:@selector(imageDownloader:didFinishWithImage:)]){
        UIImage *image = [[UIImage alloc] initWithData:imageData];
        [delegate performSelector:@selector(imageDownloader:didFinishWithImage:) withObject:self withObject:image];
    }
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    //------------------------------2.4版本更新-功能优化-------------------------
    [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil];
    //-----------------------------------end-----------------------------------
    if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)]){
        [delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:error];
    }
    self.connection = nil;
    self.imageData = nil;
}

//------------------------------2.4版本更新-功能优化-------------------------
- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
//-----------------------------------end----------------------------------


@end

5. SDImageCache

  • 新增系统平台兼容iPhone系统TARGET_OS_IPHONE
//-----------------------2.4版本更新-系统版本兼容-----------------------
        #if TARGET_OS_IPHONE
        //--------------------------------end--------------------------------
        //订阅应用程序事件
        //应用程序终止,里面回调didReceiveMemoryWarning方法,清空内存
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(clearMemory)
                                        name:UIApplicationDidReceiveMemoryWarningNotification
                                                   object:nil];
        //应用程序终止,里面回调willTerminate方法,清空磁盘
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(cleanDisk)
                                                name:UIApplicationWillTerminateNotification
                                                   object:nil];

        //-----------------------2.1版本更新-系统版本兼容-----------------------
        #ifdef __IPHONE_4_0
       
        UIDevice *device = [UIDevice currentDevice];
        if ([device respondsToSelector:@selector(isMultitaskingSupported)] && device.multitaskingSupported){
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(clearMemory)
                                                         name:UIApplicationDidEnterBackgroundNotification
                                                       object:nil];
        }
       
        #endif
        //--------------------------------end--------------------------------
        #endif
  • 将图片数据缓存磁盘支持了TARGET_OS_IPHONE
- (void)storeKeyWithDataToDisk:(NSArray *)keyAndData{
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    NSString *key = [keyAndData objectAtIndex:0];
    NSData *data = [keyAndData count] > 1 ? [keyAndData objectAtIndex:1] : nil;
    if (data){
        [fileManager createFileAtPath:[self cachePathForKey:key] contents:data attributes:nil];
    } else {
        //如果没有给定的数据表示,转换JPEG中的UIImage并存储它
        //这个技巧占用更多的CPU/内存,并且不保留alpha通道
        //线程安全,没有锁
        UIImage *image = [self imageFromKey:key fromDisk:YES];
        if (image){
            //-----------------------2.4版本更新-系统版本兼容-----------------------
            #if TARGET_OS_IPHONE
            [fileManager createFileAtPath:[self cachePathForKey:key] contents:UIImageJPEGRepresentation(image, (CGFloat)1.0) attributes:nil];
            #else
            NSArray* representations  = [image representations];
            NSData* jpegData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSJPEGFileType properties:nil];
            [fileManager createFileAtPath:[self cachePathForKey:key] contents:jpegData attributes:nil];
            #endif
            //--------------------------------end--------------------------------
        }
    }
}
  • 图片缓存优化
- (void)storeImage:(UIImage *)image imageData:(NSData *)data forKey:(NSString *)key toDisk:(BOOL)toDisk{
    //-----------------------2.4版本更新-功能优化-----------------------
    if (!image || !key){
        return;
    }
    [memCache setObject:image forKey:key];
    if (toDisk){
        if (!data)
            return;
        NSArray *keyWithData;
        if (data){
            keyWithData = [NSArray arrayWithObjects:key, data, nil];
        }else{
            keyWithData = [NSArray arrayWithObjects:key, nil];
        }
        [cacheInQueue addOperation:[[NSInvocationOperation alloc] initWithTarget:self
 selector:@selector(storeKeyWithDataToDisk:) object:keyWithData]];
    }
    //------------------------------end------------------------------
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容