當前位置:
首頁 > 知識 > iOS多線程開發之NSOperation-快上車,沒時間解釋了!

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

一、什麼是NSOperation?

NSOperation是蘋果提供的一套多線程解決方案。實際上NSOperation是基於GCD更高一層的封裝,但是比GCD更加的面向對象、代碼可讀性更高、可控性更強,很屌的是加入了操作依賴。

默認情況下,NSOperation單獨使用時只能同步執行操作,並沒有開闢新線程的能力,只有配合NSOperationQueue才能實現非同步執行。講到這裡,我們不難發現GCD和NSOperation實現的方式很像,其實這更像是廢話,NSOperation本身就是基於GCD的封裝,NSOperation相當於GCD中的任務,而NSOperationQueue則相當於GCD中的隊列,前面《iOS多線程開發之GCD(上篇)》中已經闡述過GCD的實質:開發者要做的只是定義想執行的任務並追加到適當的Dispatch Queue中。這樣我們也可說NSOperation的本質就是:定義想執行的任務(NSOperation)並追加到適當的NSOperationQueue中。

二、NSOperation使用

1、創建任務

NSOperation是一個抽象的基類,表示一個獨立的計算單元,可以為子類提供有用且線程安全的建立狀態,優先順序,依賴和取消等操作。但它不能直接用來封裝任務,只能通過它的子類來封裝,一般的我們可以使用:NSBlockOperation、NSInvocationOperation或者定義繼承自NSOperation的子類,通過實現內部相應的方法來封裝任務。

(1)NSBlockOperation

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)invocationOperation{

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

執行結果:

2017-07-14 13:43:59.327 beck.wang[10248:1471363] start - {number = 1, name = main}2017-07-14 13:43:59.328 beck.wang[10248:1471363] invocationOperation -- {number = 1, name = main}2017-07-14 13:43:59.328 beck.wang[10248:1471363] end - {number = 1, name = main}

分析:單獨使用NSInvocationOperation的情況下,NSInvocationOperation在主線程同步執行操作,並沒有開啟新線程。

(2)NSBlockOperation

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)blockOperation{

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

列印結果:

2017-07-14 13:49:25.436 beck.wang[10304:1476355] start - {number = 1, name = main}2017-07-14 13:49:25.436 beck.wang[10304:1476355] end - {number = 1, name = main}2017-07-14 13:49:25.436 beck.wang[10304:1476355] blockOperation--{number = 1, name = main}

分析:單獨使用NSBlockOperation的情況下,NSBlockOperation也是在主線程執行操作,沒有開啟新線程。

值得注意的是:NSBlockOperation還提供了一個方法addExecutionBlock:,通過addExecutionBlock:就可以為NSBlockOperation添加額外的操作,這些額外的操作就會在其他線程並發執行。

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)blockOperation{

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

列印結果:

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

2017-07-14 13:57:02.009 beck.wang[10351:1482603] start - {number = 1, name = main}2017-07-14 13:57:02.009 beck.wang[10351:1482603] end - {number = 1, name = main}2017-07-14 13:57:02.010 beck.wang[10351:1482603] blockOperation--{number = 1, name = main}2017-07-14 13:57:02.010 beck.wang[10351:1482642] addTask1---{number = 3, name = (null)}2017-07-14 13:57:02.010 beck.wang[10351:1482645] addTask3---{number = 5, name = (null)}2017-07-14 13:57:02.010 beck.wang[10351:1482643] addTask2---{number = 4, name = (null)}

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

分析:blockOperationWithBlock任務在主線程中執行,addExecutionBlock的任務在新開線程中執行。

(3)自定義NSOperation子類--重寫main方法即可

.h

@interface ZTOperation : NSOperation@end

.m

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

@implementation ZTOperation- (void)main{ // 在這裡可以自定義任務

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

ViewController

ZTOperation *zt = [[ZTOperation alloc] init];

列印結果:

2017-07-14 14:05:58.824 beck.wang[10389:1490955] ZTOperation--{number = 1, name = main}

分析:任務在主線程中執行,不開啟新線程。

2、創建隊列

NSOperationQueue一共有兩種隊列:主隊列、其他隊列。其中其他隊列同時包含了串列、並發功能,通過設置最大並發數maxConcurrentOperationCount來實現串列、並發!

(1)主隊列 -- 任務在主線程中執行

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];

(2)其他隊列 -- 任務在子線程中執行

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

3、NSOperation + NSOperationQueue (任務追加到隊列)

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

// 添加單個操作:

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

代碼示例:

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)addOperationToQueue

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

列印結果:

2017-07-14 14:39:51.669 beck.wang[10536:1516641] start - {number = 1, name = main}2017-07-14 14:39:51.670 beck.wang[10536:1516641] end - {number = 1, name = main}2017-07-14 14:39:51.670 beck.wang[10536:1516686] task003-----{number = 3, name = (null)}2017-07-14 14:39:51.670 beck.wang[10536:1516689] task002 -- {number = 5, name = (null)}2017-07-14 14:39:51.670 beck.wang[10536:1516687] task001 -- {number = 4, name = (null)}

分析:開啟新線程,並發執行。

三、NSOperationQueue管理

1、隊列的取消、暫停、恢復

- (void)cancel; NSOperation提供的方法,可取消單個操作

- (void)cancelAllOperations; NSOperationQueue提供的方法,可以取消隊列的所有操作

- (void)setSuspended:(BOOL)b; 可設置任務的暫停和恢復,YES代表暫停隊列,NO代表恢復隊列

- (BOOL)isSuspended; 判斷暫停狀態

暫停或取消並不能使正在執行的操作立即暫停或取消,而是當前操作執行完後不再執行新的操作。兩者的區別在於暫停操作之後還可以恢復操作,繼續向下執行;而取消操作之後,所有的操作就清空了,無法再接著執行剩下的操作。

2、最大並發數 maxConcurrentOperationCount

maxConcurrentOperationCount = - 1 表示不限制,默認並發執行;

maxConcurrentOperationCount = 1 表示最大並發數為1,串列執行;

maxConcurrentOperationCount > ([count] > =1) 表示並發執行,min[count,系統限制]。

代碼示例:

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)operationQueue

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

列印結果:

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

// queue.maxConcurrentOperationCount = - 12017-07-14 15:28:39.554 beck.wang[10772:1557342] task2-----{number = 4, name = (null)}2017-07-14 15:28:39.554 beck.wang[10772:1557358] task3-----{number = 5, name = (null)}2017-07-14 15:28:39.554 beck.wang[10772:1557359] task4-----{number = 6, name = (null)}2017-07-14 15:28:39.554 beck.wang[10772:1557339] task5-----{number = 7, name = (null)}2017-07-14 15:28:39.554 beck.wang[10772:1557340] task1-----{number = 3, name = (null)}2017-07-14 15:28:39.554 beck.wang[10772:1557360] task6-----{number = 8, name = (null)}// 分析:線程數為6,並發執行-----------------------------------分割線----------------------------------------------// queue.maxConcurrentOperationCount = 12017-07-14 15:27:04.365 beck.wang[10743:1555231] task1-----{number = 3, name = (null)}2017-07-14 15:27:04.365 beck.wang[10743:1555231] task2-----{number = 3, name = (null)}2017-07-14 15:27:04.365 beck.wang[10743:1555231] task3-----{number = 3, name = (null)}2017-07-14 15:27:04.365 beck.wang[10743:1555231] task4-----{number = 3, name = (null)}2017-07-14 15:27:04.366 beck.wang[10743:1555231] task5-----{number = 3, name = (null)}2017-07-14 15:27:04.366 beck.wang[10743:1555231] task6-----{number = 3, name = (null)}// 分析:線程個數為1,同步執行-----------------------------------分割線----------------------------------------------// queue.maxConcurrentOperationCount = 22017-07-14 15:18:26.162 beck.wang[10715:1548342] task2-----{number = 4, name = (null)}2017-07-14 15:18:26.162 beck.wang[10715:1548344] task1-----{number = 3, name = (null)}2017-07-14 15:18:26.162 beck.wang[10715:1548342] task4-----{number = 4, name = (null)}2017-07-14 15:18:26.162 beck.wang[10715:1548344] task3-----{number = 3, name = (null)}2017-07-14 15:18:26.162 beck.wang[10715:1548342] task5-----{number = 4, name = (null)}2017-07-14 15:18:26.163 beck.wang[10715:1548344] task6-----{number = 3, name = (null)}// 分析:線程個數為2,並發執行

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

很明顯,通過設置maxConcurrentOperationCount就能實現並發、串列功能是不是比GCD輕鬆多了!

3、操作依賴

NSOperation中我們可以為操作分解為若干個小的任務,通過添加他們之間的依賴關係進行操作,這個經常用到!這也是NSOperation吸引人的地方,不需要像GCD那樣使用複雜的代碼實現,addDependency就可以搞定!

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)addDependency

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

列印結果:

2017-07-14 15:46:02.011 beck.wang[10854:1571574] task3-----{number = 3, name = (null)}2017-07-14 15:46:04.085 beck.wang[10854:1571596] task1-----{number = 4, name = (null)}2017-07-14 15:46:04.085 beck.wang[10854:1571574] task2-----{number = 3, name = (null)}

分析:task2一定在task1後面執行,因為執行task1前設置了線程等待2s,所有task3最早執行。

4、操作優先順序

NSOperationQueuePriorityVeryLow = -8L,

5、操作的監聽

可以監聽一個操作是否執行完畢,如下載圖片,需要在下載第一張圖片後才能下載第二張圖片,這裡就可以設置監聽。

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

- (void)addListing{

iOS多線程開發之NSOperation-快上車,沒時間解釋了!

執行結果:

2017-07-14 16:21:43.833 beck.wang[10930:1597954] 下載圖片1-{number = 3, name = (null)}2017-07-14 16:21:43.834 beck.wang[10930:1597954] 下載圖片1-{number = 3, name = (null)}2017-07-14 16:21:43.834 beck.wang[10930:1597954] 下載圖片1-{number = 3, name = (null)}2017-07-14 16:21:43.834 beck.wang[10930:1597955] --下載圖片2--

分析:下載圖片1完成後才會執行下載圖片2,這裡類似知識點3中的添加依賴。

留在最後的話:多線程不只是有GCD!如果你還沒有用過NSOperation,還說什麼呢?趕緊操練起來!當然他們各有各的使用場景,存在即合理!iOS多線程的三種技術GCD、NSThread、NSOperation就都介紹完了,需要了解 GCD、NSThread的可以回頭看看我之前的博客。

學安卓,免學費!50天興趣課程等你來搶!http://www.ujiuye.com/xydt/2017/13042.html?wt.bd=ldd37299tt

2017大學生就業扶助基金:http://www.ujiuye.com/zt/jyfc/?wt.bd=ldd37299tt

IT學習就業交流互動平台:http://www.ujiuye.com/zt/qqhdjlpt/?wt.bd=ldd37299tt

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT優就業 的精彩文章:

基於springmvc的hessian調用原理淺析
58 同城 iOS 客戶端 Hybrid 框架探索
「租賃」這頭豬,怎麼就趴上「共享」這個風口上了呢?

TAG:IT優就業 |

您可能感興趣

Android之父Essential Phone將停止開發,並出售其公司
Android開發者是時候轉向Kotlin了
iPhone SE2,徹底涼了!蘋果開發者大會:沒有iPhone SE2計劃!
Mixed Reality Toolkit-Unity開發系列—Sharing模塊
Android 9.0 開發代號定為「Pistachio Ice Cream」,有哪些功能期待被改進?
BCH新開發者平台Developer.bitcoin上線,加速BCH應用開發
Facebook:一批開發者已經拿到了Santa Cruz開發機
watchOS 5 將停止支持為 watchOS 1 開發的應用
VMWare Fusion Pro 10-macOS 強大虛擬機軟體,開發者的福音
iOS11開發者預計下周放出Electra for Cydia公開版!
繼 Linux 之父之後獨立開發者 Jonathan Blow 再次炮轟 C++ 可怕
iOS 12 beta 5 開發者測試版暗示「iPhone X Plus」將有 iPad 的橫屏模式
Adobe正在為 iPad開發一款Photoshop完整版,據報道明年推出上架
開發者再爆料:LCD版的iPhone就是iPhoneSE2
iOS開發 適配iPhoneX/iPhoneXr/iPhoneXs/iPhonexs max
Mozilla發布Firefox Reality WebVR開發者指南
Justin Timberlake 著用未公開發售「Air Higher」Air Jordan 3 Sample
Google發布Android KTX預覽版,它能為Kotlin開發者做些什麼?
適用於Android和iPhone的Swype鍵盤停止開發
引入Skaffold:簡單且可重複的Kubernetes開發