簡介
NSOperation的作用
- NSOperation和NSOperationQueue配合使用也能實現多線程編程
NSOperation和NSOperationQueue實現多線程的具體步驟
- 先將需要執行的操作封裝到一個NSOperation對象中
- 然後將NSOperation對象添加到NSOperationQueue中
- 系統會自動將NSOperationQueue中的NSOperation取出來
- 將取出的NSOperation封裝的操作放到一條新線程中執行
NSOperation的子類
NSOperation是個抽象類,並不具備封裝操作的能力,必須使用它的子類
使用NSOperation子類的方式有3種
- NSInvocationOperation
- NSBlockOperation
- 自定義子類繼承NSOperation,實現內部相應的方法
NSInvocationOperation
創建NSInvocationOperation對象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
調用start方法開始執行操作
- (void)start;
- 一旦執行操作,就會調用target的sel方法
注意
- 默認情況下,調用了start方法後並不會開一條新線程去執行操作,而是在當前線程同步執行操作
只有將NSOperation放到一個NSOperationQueue中,纔會異步執行操作
- 默認情況下,調用了start方法後並不會開一條新線程去執行操作,而是在當前線程同步執行操作
NSBlockOperation
創建NSBlockOperation對象
- (id)blockOperationWithBlock:(void (^)(void))block;
通過addExecutionBlock:方法添加更多的操作
- (void)addExecutionBlock:(void (^)(void))block;
注意:只要NSBlockOperation封裝的操作數 > 1,就會異步執行操作
NSOperationQueue
NSOperationQueue的作用
- NSOperation可以調用start方法來執行任務,但默認是同步執行的
- 如果將NSOperation添加到NSOperationQueue(操作隊列)中,系統會自動異步執行NSOperation中的操作
添加操作到NSOperationQueue中
- (void)addOperation:(NSOperation *)op;
- (void)addOperationWithBlock:(void (^)(void))block;
最大併發數
什麼是併發數
- 同時執行的任務數
- 比如,同時開3個線程執行3個任務,併發數就是3
最大併發數的相關方法
- (NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
隊列的取消、暫停、恢復
取消隊列的所有操作
- (void)cancelAllOperations;
- 提示:也可以調用NSOperation的- (void)cancel方法取消單個操作
暫停和恢復隊列
- (void)setSuspended:(BOOL)b; // YES代表暫停隊列,NO代表恢復隊列
- (BOOL)isSuspended;
操作依賴
NSOperation之間可以設置依賴來保證執行順序
- 比如一定要讓操作A執行完後,才能執行操作B,可以這麼寫
- [operationB addDependency:operationA]; // 操作B依賴於操作A
可以在不同queue的NSOperation之間創建依賴關係
操作的監聽
- 可以監聽一個操作的執行完畢
- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;
自定義NSOperation
自定義NSOperation的步驟很簡單
- 重寫- (void)main方法,在裏面實現想執行的任務
重寫- (void)main方法的注意點
- 自己創建自動釋放池(因爲如果是異步操作,無法訪問主線程的自動釋放池)
- 經常通過- (BOOL)isCancelled方法檢測操作是否被取消,對取消做出響應
線程間通信
-(void)download
{
// 1.開子線程下載圖片
// 1.1 非主隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// 1.2 封裝操作
NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"download url"];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData];
NSLog(@"download---%@",[NSThread currentThread]);
// 3.更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
NSLog(@"UI---%@",[NSThread currentThread]);
}];
}];
// 2.添加操作到隊列
[queue addOperation:download];
}