04NSOperationQueue

一、簡介
一個NSOperation對象可以通過調用start方法來執行任務,默認是同步執行的。也可以將NSOperation添加到一個NSOperationQueue(操作隊列)中去執行,而且是異步執行的。
創建一個操作隊列:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];  

二、添加NSOperation到NSOperationQueue中
1.添加一個operation

[queue addOperation:operation];  

2.添加一組operation

[queue addOperations:operations waitUntilFinished:NO];  

3.添加一個block形式的operation

[queue addOperationWithBlock:^() {  
    NSLog(@"執行一個新的操作,線程:%@", [NSThread currentThread]);  
}];  

NSOperation添加到queue之后,通常短時間內就會得到運行。但是如果存在依賴,或者整個queue被暫停等原因,也可能需要等待。
注意:NSOperation添加到queue之后,絕對不要再修改NSOperation對象的狀態。因為NSOperation對象可能會在任何時候運行,因此改變NSOperation對象的依賴或數據會產生不利的影響。你只能查看NSOperation對象的狀態, 比如是否正在運行、等待運行、已經完成等

三、添加NSOperation的依賴對象1.當某個NSOperation對象依賴于其它NSOperation對象的完成時,就可以通過addDependency方法添加一個或者多個依賴的對象,只有所有依賴的對象都已經完成操作,當前NSOperation對象才會開始執行操作。另外,通過removeDependency方法來刪除依賴對象。

[operation2 addDependency:operation1];  

依賴關系不局限于相同queue中的NSOperation對象,NSOperation對象會管理自己的依賴, 因此完全可以在不同的queue之間的NSOperation對象創建依賴關系

依賴對象

唯一的限制是不能創建環形依賴,比如A依賴B,B依賴A,這是錯誤的

2.依賴關系會影響到NSOperation對象在queue中的執行順序,看下面的例子:
1> 沒有設置依賴關系

NSOperationQueue *queue = [[NSOperationQueue alloc] init];  

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){  
      NSLog(@"執行第1次操作,線程:%@", [NSThread currentThread]);  
}];    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){  
      NSLog(@"執行第2次操作,線程:%@", [NSThread currentThread]);  
}];  

[queue addOperation:operation1];  
[queue addOperation:operation2]; 

打印信息:

2013-02-03 00:21:35.024 thread[5616:3d13] 執行第1次操作,線程:<NSThread: 0x7658570>
{name = (null), num = 3}  
2013-02-03 00:21:35.063 thread[5616:1303] 執行第2次操作,線程:<NSThread: 0x765a2e0>    
{name = (null), num = 4}  

可以看出,默認是按照添加順序執行的,先執行operation1,再執行operation2
2> 設置了依賴關系

NSOperationQueue *queue = [[NSOperationQueue alloc] init];  

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){  
     NSLog(@"執行第1次操作,線程:%@", [NSThread currentThread]);  
}];  

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){  
     NSLog(@"執行第2次操作,線程:%@", [NSThread currentThread]);  
}];  
// operation1依賴于operation2  
[operation1 addDependency:operation2];  

[queue addOperation:operation1];  
[queue addOperation:operation2];  

打印信息:

2013-02-03 00:24:16.260 thread[5656:1b03] 執行第2次操作,線程:<NSThread: 0x7634490>
{name = (null), num = 3}  
2013-02-03 00:24:16.285 thread[5656:1303] 執行第1次操作,線程:<NSThread: 0x9138b50>     
{name = (null), num = 4}  

可以看出,先執行operation2,再執行operation1

四、修改Operations的執行順序
對于添加到queue中的operations,它們的執行順序取決于2點:
1.首先看看NSOperation是否已經準備好:是否準備好由對象的依賴關系確定
2.然后再根據所有NSOperation的相對優先級來確定。優先級等級則是operation對象本身的一個屬性。默認所有operation都擁有“普通”優先級,不過可以通過setQueuePriority:方法來提升或降低operation對象的優先級。優先級只能應用于相同queue中的operations。如果應用有多個operation queue,每個queue的優先級等級是互相獨立的。因此不同queue中的低優先級操作仍然可能比高優先級操作更早執行。
注意:優先級不能替代依賴關系,優先級只是對已經準備好的 operations確定執行順序。先滿足依賴關系,然后再根據優先級從所有準備好的操作中選擇優先級最高的那個執行。

五、設置隊列的最大并發操作數量
隊列的最大并發操作數量,意思是隊列中最多同時運行幾條線程
雖然NSOperationQueue類設計用于并發執行Operations,你也可以強制單個queue一次只能執行一個Operation。setMaxConcurrentOperationCount:方法可以配置queue的最大并發操作數量。設為1就表示queue每次只能執行一個操作。不過operation執行的順序仍然依賴于其它因素,比如operation是否準備好和operation的優先級等。因此串行化的operation queue并不等同于GCD中的串行dispatch queue

// 每次只能執行一個操作  
queue.maxConcurrentOperationCount = 1;  
// 或者這樣寫  
[queue setMaxConcurrentOperationCount:1];  

六、取消Operations
一旦添加到operation queue,queue就擁有了這個Operation對象并且不能被刪除,唯一能做的事情是取消。你可以調用Operation對象的cancel方法取消單個操作,也可以調用operation queue的cancelAllOperations方法取消當前queue中的所有操作。

// 取消單個操作  
[operation cancel];  

// 取消queue中所有的操作  
[queue cancelAllOperations];  

七、等待Options完成
為了最佳的性能,你應該設計你的應用盡可能地異步操作,讓應用在Operation正在執行時可以去處理其它事情。如果需要在當前線程中處理operation完成后的結果,可以使用NSOperation的waitUntilFinished方法阻塞當前線程,等待operation完成。通常我們應該避免編寫這樣的代碼,阻塞當前線程可能是一種簡便的解決方案,但是它引入了更多的串行代碼,限制了整個應用的并發性,同時也降低了用戶體驗。絕對不要在應用主線程中等待一個Operation,只能在第二或次要線程中等待。阻塞主線程將導致應用無法響應用戶事件,應用也將表現為無響應。

// 會阻塞當前線程,等到某個operation執行完畢  
[operation waitUntilFinished];  

除了等待單個Operation完成,你也可以同時等待一個queue中的所有操作,使用NSOperationQueue的waitUntilAllOperationsAreFinished方法。注意:在等待一個 queue時,應用的其它線程仍然可以往queue中添加Operation,因此可能會加長線程的等待時間。

// 阻塞當前線程,等待queue的所有操作執行完畢  
[queue waitUntilAllOperationsAreFinished]; 

八、暫停和繼續queue
如果你想臨時暫停Operations的執行,可以使用queue的setSuspended:方法暫停queue。不過暫停一個queue不會導致正在執行的operation在任務中途暫停,只是簡單地阻止調度新Operation執行。你可以在響應用戶請求時,暫停一個queue來暫停等待中的任務。稍后根據用戶的請求,可以再次調用setSuspended:方法繼續queue中operation的執行

// 暫停queue  
[queue setSuspended:YES];  

// 繼續queue  
[queue setSuspended:NO];  
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容