天天看點

iOS多線程程式設計之二——NSOperation與NSOperationQueue

nsoperation是基于object-c封裝的一套管理與執行線程操作的類。這個類是一個抽象類,通常情況下,我們會使用nsinvocationoperation和nsblockoperation這兩個子類進行多線程的開發,當然我們也可以寫繼承于nsoperation的類,封裝我們自己的操作類。

操作開始執行

<a href="http://my.oschina.net/u/2340880/blog/416782#">?</a>

1

<code>- (</code><code>void</code><code>)start;</code>

在子類中可以重寫這個方法,實作執行的方法

<code>- (</code><code>void</code><code>)main;</code>

取消執行

<code>- (</code><code>void</code><code>)cancel;</code>

擷取當操作狀态的幾個屬性

2

3

4

5

<code>@property (readonly, getter=iscancelled) </code><code>bool</code> <code>cancelled;</code><code>//目前操作是否取消執行</code>

<code>@property (readonly, getter=isexecuting) </code><code>bool</code> <code>executing;</code><code>//目前操作是否正在執行</code>

<code>@property (readonly, getter=isfinished) </code><code>bool</code> <code>finished;</code><code>//目前操作是否執行結束</code>

<code>@property (readonly, getter=isasynchronous) </code><code>bool</code> <code>asynchronous;</code><code>//目前操作是否在異步線程中</code>

<code>@property (readonly, getter=isready) </code><code>bool</code> <code>ready;</code><code>//目前操作是否已經準備好</code>

阻塞目前線程直到操作完成

<code>- (</code><code>void</code><code>)waituntilfinished;</code>

設定在操作隊列中的優先級

<code>@property nsoperationqueuepriority queuepriority;</code>

其中nsoperationqueuepriority的枚舉如下:

6

7

<code>typedef</code> <code>ns_enum(nsinteger, nsoperationqueuepriority) {</code>

<code>    </code><code>nsoperationqueuepriorityverylow = -8l,</code><code>//優先級很低</code>

<code>    </code><code>nsoperationqueueprioritylow = -4l,</code><code>//優先級低</code>

<code>    </code><code>nsoperationqueueprioritynormal = 0,</code><code>//優先級普通</code>

<code>    </code><code>nsoperationqueuepriorityhigh = 4,</code><code>//優先級高</code>

<code>    </code><code>nsoperationqueuepriorityveryhigh = 8</code><code>//優先級非常高</code>

<code>};</code>

設定操作完成後的回調block

<code>@property (copy) </code><code>void</code> <code>(^completionblock)(</code><code>void</code><code>);</code>

設定操作的優先級

<code>@property </code><code>double</code> <code>threadpriority;</code>

設定操作的名稱

<code>@property (copy) nsstring *name;</code>

nsblockoperation是nsoperation的一個子類,其可以異步的執行多個block,當所有的block都完成時,這個操作才算完成。

初始化方法:

<code>+ (instancetype)blockoperationwithblock:(</code><code>void</code> <code>(^)(</code><code>void</code><code>))block;</code>

在操作中添加block

<code>- (</code><code>void</code><code>)addexecutionblock:(</code><code>void</code> <code>(^)(</code><code>void</code><code>))block;</code>

添加進去的block的數組

<code>@property (readonly, copy) nsarray *executionblocks;</code>

示例如下:

8

9

10

11

<code>nsblockoperation * opera = [nsblockoperation blockoperationwithblock:^{</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;10; i++) {</code>

<code>            </code><code>nslog(@</code><code>"%@=%d"</code><code>,[nsthread currentthread],i);</code>

<code>        </code><code>}</code>

<code>    </code><code>}];</code>

<code>    </code><code>[opera addexecutionblock:^{</code>

<code>    </code><code>[opera start];</code>

列印情況如下,可以看出,兩個block塊的執行是異步的:

iOS多線程程式設計之二——NSOperation與NSOperationQueue

根據選擇器建立一個對象

<code>- (instancetype)initwithtarget:(id)target selector:(sel)sel object:(id)arg;</code>

通過invocation建立一個對象

<code>- (instancetype)initwithinvocation:(nsinvocation *)inv;</code>

這個類執行的操作是與調用它的線程同步的,示例如下:

12

13

14

15

16

<code>- (</code><code>void</code><code>)viewdidload {</code>

<code>    </code><code>[super viewdidload];</code>

<code>    </code><code>// do any additional setup after loading the view, typically from a nib.  </code>

<code>    </code><code>nsinvocationoperation * operation = [[nsinvocationoperation alloc]initwithtarget:self selector:@selector(</code><code>log</code><code>) object:nil];</code>

<code>    </code><code>[operation start];</code>

<code>        </code><code>nslog(@</code><code>"%@=%d"</code><code>,[nsthread currentthread],i);</code>

<code>        </code><code>}  </code>

<code>}</code>

<code>-(</code><code>void</code><code>)</code><code>log</code><code>{</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;100; i++) {</code>

<code>    </code><code>}</code>

通過列印結果可以看出其執行的同步性。

依賴關系和優先級的作用很像,卻也不同。如果一個操作a依賴于另一個操作b,那麼隻有當b操作完成後,a操作才會執行。操作添加依賴的

添加一個依賴:

<code>- (</code><code>void</code><code>)adddependency:(nsoperation *)op;</code>

删除一個依賴

<code>- (</code><code>void</code><code>)removedependency:(nsoperation *)op;</code>

原則上說,一個操作對象的依賴可以添加多個,并且當所有依賴都執行完成後才會執行這個操作。

nsoperationqueue是操作隊列類,通過上面的介紹,我們已經可以了解操作,并且操作預設的執行方式是串行的,盡管nsblockoperation中的block塊間是并行執行的,但其和外部操作依然是串行的。如果将操作放入操作隊列中,則預設為并行執行的。

<code>    </code><code>// do any additional setup after loading the view, typically from a nib.</code>

<code>    </code><code>nsoperationqueue * queue = [[nsoperationqueue alloc]init];</code>

<code>    </code><code>nsinvocationoperation * op1 = [[nsinvocationoperation alloc]initwithtarget:self selector:@selector(</code><code>log</code><code>) object:nil];</code>

<code>    </code><code>[queue addoperation:op1];</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;10; i++) {</code>

列印資訊如下:

iOS多線程程式設計之二——NSOperation與NSOperationQueue

可以看出來,隊列的操作是在一個新的線程中執行的,并且操作隊列之中的操作也都是異步執行的。

在操作隊列中添加一個操作任務:

<code>- (</code><code>void</code><code>)addoperation:(nsoperation *)op;</code>

在隊列中插入一組操作任務,後面的參數設定是否隊列中得任務都執行完成後再執行這一組操作:

<code>- (</code><code>void</code><code>)addoperations:(nsarray *)ops waituntilfinished:(</code><code>bool</code><code>)wait;</code>

在隊列中添加一個block操作

<code>- (</code><code>void</code><code>)addoperationwithblock:(</code><code>void</code> <code>(^)(</code><code>void</code><code>))block;</code>

擷取操作隊列中的所有操作的數組

<code>@property (readonly, copy) nsarray *operations;</code>

擷取操作隊列中操作的個數

<code>@property (readonly) nsuinteger operationcount;</code>

設定隊列最大并行操作數量

<code>@property nsinteger maxconcurrentoperationcount;</code>

設定是否暫停隊列任務執行

<code>@property (getter=issuspended) </code><code>bool</code> <code>suspended;</code>

設定隊列名字

設定隊列的優先級别(ios8後支援)

<code>@property nsqualityofservice qualityofservice;</code>

取消隊列中所有操作任務

<code>- (</code><code>void</code><code>)cancelalloperations;</code>

阻塞目前線程,直到隊列中所有任務完成

<code>- (</code><code>void</code><code>)waituntilalloperationsarefinished;</code>

擷取目前執行的隊列

<code>+ (nsoperationqueue *)currentqueue;</code>

擷取主線程中的操作隊列

<code>+ (nsoperationqueue *)mainqueue;</code>

1、決定于依賴關系,隻有當這個操作的依賴全部執行完成後,它才會被執行。

2、影響于優先級,優先級高的會先執行。

繼續閱讀