继承于NSOperation类
重写了-start方法。手动管理操作的状态,只有发送isFinished的KVO消息时,才认为是operation结束。
为了让操作队列能够捕捉到操作的改变,需要将状态的属性以配合KVO的方式进行实现。
- isExecuting 代表任务正在执行中
- isFinished 代表任务已经执行完成
- isCancelled 代表任务已经取消执行
- (void)setFinished:(BOOL)finished {
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
-start
1.线程同步锁(以self作为互斥信号量)判断cancel,如果为YES,认为该任务完成,并及时收回资源(-reset)
2.判断是否进入后台,如果进入了后台,将当前任务放到后台执行。
sself.backgroundTaskId = UIBackgroundTaskInvalid;
意思就是告诉系统,任务完成,不需要考虑进不进入后台运行的问题了。确实,在start函数末尾,就是判断如果下载任务完成(不管有没有下载成功),就将backgroundTaskId置为UIBackgroundTaskInvalid。
3、初始化NSURLConnection [self.connection start];
4.connection 创建成功,返回进度(0,size)。
5.发送开始的通知:SDWebImageDownloadStartNotification
6.runloop 开启
7.判断 isFinished 属性,如果为no,取消网络,返回报错信息。回收资源。
-cancel
- (void)cancel {
@synchronized (self) {
if (self.thread) {
[self performSelector:@selector(cancelInternalAndStop) onThread:self.thread withObject:nil waitUntilDone:NO];
}
else {
[self cancelInternal];
}
}
}
每个NSTread都会有一个CFRunLoop ,所以要取消的话,要stop这个RunLoop。所以self.thread存在的话,要stop runloop
- (void)cancelInternal
- 调用自定义的cancelBlock。
- 调用NSURLConnection的cancel取消self.connection。
- 回收资源。
取消操作 isCancelled并没有实时操作,在start时检测一次,重写了cancel 方法 , 回调cancelBlock,网络请求取消,状态设置,并发了一个通知 SDWebImageDownloadStopNotification。将线程停止,属性置为空。
完成状态:-done 设置finished,executing状态,属性置为空。
网络请求 didReceiveData方法:
imageData 数组 添加 接收到的data
计算方向,图片高度快读朝向,orientation属性用来记录方向。
然后解决失真问题
网络请求成功:将请求的数据arr(image)转化为UIImage,将url缓存到[SDWebImageManager sharedManager]中,
SDScaledImageForKey方法: 对图片进行缩放(根据屏幕),然后进行解压 -decodedImageWithImage