iOS - NSOperation與NSOperationQueue
作者:Mitchell
一、NSOperation簡介
- NSOperation 的作用
配合使用 NSOperation 和 NSOperationQueue 也能實現多執行緒程式設計 - NSOperation 和 NSOperationQueue 實現多執行緒的具體步驟
- 先將需要執行的操作封裝到一個 NSOperation 物件中
- 然後將 NSOperation 物件新增到 NSOperationQueue 中
- 系統會自動將 NSOperationQueue 中的 NSOperation 取出來
- 將取出來的 NSOperation 封裝的操作放到一條新執行緒中執行
- 簡單建立:
- 建立佇列
- 自己建立:alloc/init --> 預設是併發 -->也可以序列
- 主對列:mainQueue
- 因為NSOperation 沒有新增方法不能封裝操作所以不能直接使用,兩種任務方式:
NSInvocationOperation、NSBlockOperation
- 建立佇列
二、NSInvocationOperation
- 因為 NSOperation 沒有新增操作方法,所以 NSOperation 不能直接使用,使用 NSInvocationOperation、NSBlockOperation來建立:
- NSInvocationOperation 建立步驟:
- 1、將操作封裝到 Operation 中
- 2、執行封裝的操作
- 注意:如果直接執行 NSInvocationOperation 中的操作,那麼預設會在主執行緒中執行
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(demo) object:nil];
[op1 start];
三、NSBlockOperation
- 建立過程
- 1、將操作封裝到Operation中
- 2、新增操作
- 注意:
- 如果只封裝了一個操作,那麼預設會在主執行緒執行
- 如果封裝了多個操作,那麼除了第一個操作以外,其他的操作會線上程執行
//1、將操作封裝到Operation中
NSBlockOperation*op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1 - %@",[NSThread currentThread]);
}];
//2、新增操作
//如果只封裝了一個操作,那麼預設會在主執行緒執行
//如果封裝了多個操作,那麼除了第一個操作以外,其他的操作會在子執行緒執行
[op addExecutionBlock:^{
NSLog(@"2 - %@",[NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"3 - %@",[NSThread currentThread]);
}];
四、自定義Operation
- 封裝的操作:
- 如果是自定義類繼承與 NSOperation,那麼需要將操作寫到自定義類的 main 方法中
- 這種實現方式,可以提高程式碼的複用性
(可以將 block 中程式碼的實現寫在 main 函式內)
MitchellOperation*op = [[MitchellOperation alloc]init];
[op start];
#import "MitchellOperation.h"
@implementation MitchellOperation
-(void)main{
//在這裡自定義耗時的操作
NSLog(@"%s%@",__func__,[NSThread currentThread]);
}
@end
五、NSOperationQueue
- 建立順序:
- 封裝任務
- 將任務新增到佇列
- 注意:
- 只要將任務新增到自己建立的佇列中,那麼佇列內部會自動呼叫 start 。
- 只要將任務新增到佇列中,就會開啟一個新的執行緒執行佇列
- 根據傳入的block,建立一個 NSBlockOperation 物件
- 將建立好的 NSBlockOperation 物件,新增到佇列中
1、建立佇列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
2、封裝任務
2.1 NSInvocationOperation
NSInvocationOperation*op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(demo) object:nil];
2.2 NSBlockOperation
NSBlockOperation*op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
}];
3、將任務新增到佇列
[queue addOperation:op1];
[queue addOperation:op2];
六、NSOperationQueue 的序列與併發
- 預設是併發
- 如果想實現序列,那麼設定
maxConcurrentOperationCount = 0
- 注意:最大併發數,不能設定位0,否則任務不會被執行,如果想在主執行緒中執行任務,那麼直接建立 mainQueue 即可。
七、NSOperationQueue 暫停、恢復、取消
- 暫停佇列中的任務
- YES 需要暫停
- NO 恢復執行
-
注意:
- 如果再任務執行的過程中暫停佇列的任務,那麼當前正在執行的任務並不會被暫停,而是會暫停佇列中的下一個任務。
- 恢復任務,是從佇列第一個沒有被執行過的任務開始恢復。
self.queue.suspended = !self.queue.suspended;
+取消任務:
- 注意:
* 取消任務和暫停任務一樣,不會取消當前正在執行的任務。
* 所以當執行耗時操作的時候,每執行一段程式碼之後就應該判斷一下當前操作是否被取消,可以節約效能。
[self.queue cancelAllOperations];
八、NSOperationQueue 任務間的依賴和監聽
- 依賴:
[op2 addDependency:op1];
- 監聽:
op1.completionBlock = ^(){
NSLog(@"圖片1下載完畢");
};
- 例項
NSOperationQueue*queue = [[NSOperationQueue alloc]init];
//下第一張圖片
NSOperation*op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載1");
}];
//下第二張圖片
NSOperation*op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載2");
}];
NSOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載3");
//回主執行緒渲染圖片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"渲染");
}];
}];
//監聽任務是否執行完畢
op1.completionBlock = ^(){
NSLog(@"圖片1下載完畢");
};
op2.completionBlock = ^(){
NSLog(@"圖片2下載完畢");
};
//新增依賴
//只要新增了依賴,那麼就會等到依賴的任務執行完畢,才會執行當前任務
//注意:
//1、新增依賴,不能新增迴圈依賴
//2、NSOperation可以跨佇列新增依賴
[op2 addDependency:op1];
[op3 addDependency:op2];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
相關文章
- NSOperation, NSOperationQueue 原理探析
- iOS 多執行緒:『NSOperation、NSOperationQueue』詳盡總結iOS執行緒
- iOS多執行緒:『NSOperation、NSOperationQueue』詳盡總結iOS執行緒
- iOS多執行緒程式設計之NSOperation和NSOperationQueue的使用iOS執行緒程式設計
- iOS 多執行緒之NSOperationQueueiOS執行緒
- iOS NSOperation的基本使用iOS
- iOS 多執行緒之NSOperationiOS執行緒
- iOS多執行緒NSOperation篇iOS執行緒
- iOS多執行緒程式設計——GCD與NSOperation總結iOS執行緒程式設計GC
- iOS多執行緒:NSOperation詳解iOS執行緒
- 玩轉iOS開發:iOS中的NSOperation開發(一)iOS
- 玩轉iOS開發:iOS中的NSOperation開發(二)iOS
- GCD與NSOperation之間的區別GC
- NSOperation 高階用法之NSOperation基礎(NSOperation原始碼分析)(上)原始碼
- iOS多執行緒(Pthread、NSThread、GCD、NSOperation)iOS執行緒threadGC
- ios多執行緒程式設計(NSThread)(NSOperation )(GCD)iOS執行緒程式設計threadGC
- iOS多執行緒程式設計技術之NSThread、Cocoa NSOperation、GCDiOS執行緒程式設計threadGC
- 多執行緒之NSOperation執行緒
- GCD NSOperation 執行緒安全GC執行緒
- 執行緒9--NSOperation執行緒
- 串聯NSOperation知識點
- 還在用GCD?來看看 NSOperation 吧GC
- Cocoa深入學習:NSOperationQueue、NSRunLoop和執行緒安全OOP執行緒
- 多執行緒之 NSOperation 基礎用法執行緒
- 執行緒10--NSOperation的基本操作執行緒
- iOS併發機制(三) —— NSOperation實現多併發之建立佇列和開啟執行緒iOS佇列執行緒
- NSOperation的進階使用和簡單探討
- iOS KVC與KVOiOS
- IOS category 與 extensioniOSGo
- 多執行緒-NSOperation中使用ASIHttpRequest注意事項執行緒HTTP
- 使用NSOperation和NSURLSession封裝一個序列下載器Session封裝
- iOS 中UIWebView與WKWebViewiOSUIWebView
- iOS-autorelease與autoreleasepooliOS
- iOS 理解copy與mutableCopyiOS
- Flutter 與 iOS 功能比較FlutteriOS
- iOS KVC與KVO簡介iOS
- [JavaScript] Promise 與 Ajax/AxiosJavaScriptPromiseiOS
- iOS UDID與UUIDiOSUI