@(Third-Library Set)[SDWebImage, SDWebImageDownloaderOperation] #SDWebImage(一) SDWebImageDownloaderOperation [TOC] ##代码规范
###实例变量的初始化
代码规范这里涉及到一些官方文档提到的东西.比如说: 在内存优化管理中提到的,在初始化和dealloc中不要使用访问器方法,也就是setter或者getter.也可以理解为就是语法糖(点语法).有如下代码:
- (id)initWithRequest:(NSURLRequest *)request
inSession:(NSURLSession *)session
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
cancelled:(SDWebImageNoParamsBlock)cancelBlock {
if ((self = [super init])) {
_request = [request copy];
_shouldDecompressImages = YES;
_options = options;
_progressBlock = [progressBlock copy]; //因为是传递进来的,所以进行一次copy操作.
_completedBlock = [completedBlock copy];
_cancelBlock = [cancelBlock copy];
_executing = NO;
_finished = NO;
_expectedSize = 0;
_unownedSession = session;
responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called
}
return self;
}
可以看到用的都是带下划线的实例变量.当然这不是一定要这样,视情况而定吧.
###继承NSOperation要遵守的一些规则.
如果没有阅读过关于NSOperation开发的一些文档,那么我们很可能会忽略一些东西.比如说一些对于并发的operations,需要重写一些方法: isExecuting, isFinished, isConcurrent等等;
例如需要在改变executing和finished变量的值时,调用willChangeValueForKey:, didChangeValueForKey:这些方法;
还有在合适的时机需要去调用isCancelled,来判断当前操作是否被取消了等等.
SD中都遵守了这样的规则.在自己写代码的时候,也需要注意这些.
##后台执行任务
SD只是重写了start方法,并没有重写main方法,这点不太理解.
其在start中,设置了当程序退到后台的时候,执行了一些额外的任务,取消当前的操作. 我想应该是有很多图片加载的操作,当程序退到后台时,这些操作尚未开始,SD就将其取消了.
代码如下:
Class UIApplicationClass = NSClassFromString(@"UIApplication");
BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)];
if (hasApplication && [self shouldContinueWhenAppEntersBackground]) { //当app进入后台时,仍继续加载.
__weak __typeof__ (self) wself = self;
UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)];
self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{
__strong __typeof (wself) sself = wself;
if (sself) {
//取消队列里面的下载操作.
[sself cancel];
//下面两步是必须的
[app endBackgroundTask:sself.backgroundTaskId];
sself.backgroundTaskId = UIBackgroundTaskInvalid;
}
}];
}
具体用法可以看下文档,解释的很清楚.当调用了beginBackgroundTaskWithExpirationHandler:这个方法后,一定要调用endBackgroundTask:这个方法.
如果有多个需要在后台执行的方法,那么上述的两个方法要一一对应.
不仅仅这里用到了后台执行任务,通过看源码,我们可以了解到后台执行任务的用法,以及用途.
##304
在NSURLSessionDataDelegate的代理方法中,作者有对服务器的返回值进行了判断.比如400以上的状态码意味着请求图片失败.
400系列是请求错误, 500系列的是服务器错误.
还有一个就是304,这个304是指内容没有改变,那么服务器返回这个状态码.
如果服务器返回的是304,那么直接取消当前的Operation.
##Orientation
图片的方向问题,如果做过相机拍照的话,会发现把手机横过来拍照,这样的图片才是我们眼中的正的图片.
如果竖着手机拍的话,会发现图片显示时,方向是不对的.这里涉及到了照片的存储方式.
具体详情请看如何处理iOS中照片的方向,解释的很精彩.
##主要的流程
SD实现了一个便利构造方法,对外开放,并且接受一些参数,例如progressBlock,completedBlock,cancelBlock等.
start方法,也是关键方法.当一个NSOperation对象被添加到一个NSOperationQueue的时候,会执行start方法.
cancel方法,执行了一些取消操作,以及将实例变量置空等.
还有就是一堆的NSURLSessionDataDelegate和NSURLSessionTaskDelegate的代理方法.代理方法中还有对接收到的data进行处理,然后得到图片.这一块我没关注.
#总结
SDWebImageDownloaderOperation是下载图片的核心功能.
我在看的时候,没有关注对图片数据的处理,更多的是理解这个类的设计.
主要的就是要根据开放文档中写的Guide,遵守一些基本的规范.
以及对一些错误的处理,和取消操作的处理.
如果有什么错误,还请不吝指出.感激不尽.