本文主要講如何自定義NSOperation,以及自定義NSOperation的一些註意事項,以下載圖片為例。 新建一個類,繼承於NSOperation。 CustomOperation.h 代碼 CustomOperation.m 分析 :1.自定義NSOperation都要 ...
本文主要講如何自定義NSOperation,以及自定義NSOperation的一些註意事項,以下載圖片為例。
新建一個類,繼承於NSOperation。
CustomOperation.h
代碼
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CustomOperation : NSOperation
@property (nonatomic, copy) NSString *strURL;
@property (nonatomic, copy) void (^DownLoadImageBLock)(UIImage *image);
@end
CustomOperation.m
#import "CustomOperation.h"
@implementation CustomOperation
// 1.實現Main方法
- (void)main {
// 2.新建一個自動釋放池
@autoreleasepool {
// 3.正確響應取消事件
if (self.isCancelled) return;
NSURL *url = [NSURL URLWithString:self.strURL];
NSData *data = [NSData dataWithContentsOfURL:url];
if (self.isCancelled) {
url = nil;
data = nil;
}
UIImage *image = [UIImage imageWithData:data];
if (self.isCancelled) {
image = nil;
return;
}
// 4.把圖片傳回主線程
dispatch_async(dispatch_get_main_queue(), ^{
//5. 用block傳值
if (self.DownLoadImageBLock) {
self.DownLoadImageBLock(image);
}
});
}
}
// 6. dealloc
-(void)dealloc {
NSLog(@"operation-------dealloc");
}
分析:1.自定義NSOperation都要實現Main方法,在這個方法里寫要NSOperation執行的耗時操作。
2.新建一個自動釋放池。如果是非同步操作,不能訪問主線程的自動釋放池,所以要新建一個。
3.正確響應取消事件。在每一個耗時操作之前,都要判斷此操作是否被取消。如果取消了,就不往下執行了。因為我們有時候需要先取消下載,例如滑動tableView的時候,等不滑動了,再繼續,增加UI流暢度。
4.把圖片傳回主線程。主線程回調,因為下載完的數據肯定是要操作UI的,AFNetworking就是這樣乾的。
5.用block傳值。傳值之前判斷是否存在此block,這和代理傳值之前判斷代理是否響應了代理里的方法是一個道理。
6.dealloc方法,監測一下有沒有正確釋放記憶體。
使用自定義NSOperation
代碼
// 點擊屏幕下載圖片
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.創建一個CustomOperation對象
CustomOperation *operation1 = [[CustomOperation alloc] init];
// 2.為URL賦值
operation1.strURL = @"http://h.hiphotos.baidu.com/zhidao/pic/item/6d81800a19d8bc3ed69473cb848ba61ea8d34516.jpg";
// 3.處理block傳回來的結果
operation1.DownLoadImageBLock = ^(UIImage *image) {
self.imageView1.image = image;
};
// 4.創建一個CustomOperation對象
CustomOperation *operation2 = [[CustomOperation alloc] init];
operation2.strURL = @"http://h.hiphotos.baidu.com/zhidao/pic/item/0eb30f2442a7d9334f268ca9a84bd11372f00159.jpg";
operation2.DownLoadImageBLock = ^(UIImage *image) {
self.imageView2.image = image;
};
// 5.創建一個隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 6.把操作放入隊列中
[queue addOperation:operation1];
[queue addOperation:operation2];
}
效果
分析1. 這一步和使用系統提供的NSOperation沒有區別。
2.為自定義的NSOperation提供下載地址。
3.處理下載之後的數據。由於在自定義的NSOperation中已經是主線程回調了,所以就可以直接操作UI了。
4.同上。
5.創建一個隊列。
6..把操作放入隊列中。
自定義一個NSOperation就是這麼簡單,我們只要重寫main方法就可以,傳值的方式有多種,如果大家不習慣block,也可以用代理,都能達到效果。但是block的可讀性更高,因為代碼都寫在一起,好找。稍後我會向git上傳一個項目,是列表頁下載圖片,用自定義NSOperation寫的,有興趣的可以看看。