NSOperation, NSOperationQueue 原理探析

Lastdays發表於2016-11-23
通過GNUstep的Foundation來嘗試探索下NSOperation,NSOperationQueue

示例程式

寫一個簡單的程式

LDNSOperation為NSOperation的子類,重寫strat方法

實現的效果很簡單,列印三個strat,然後結束operation。

初探

根據閱讀GNU的原始碼,也只能是猜想,但是嘗試了很多方法,沒有找到可以驗證的方案,但是實現原理上還是有很多相似處的。

NSOperation有三種狀態,isReady, isExecuting, isFinished.

很多其他的引數也會隨著NSOperationQueue的addOperation操作而變化著。

例如:

新增一個未完成的NSOperation,其實就是將NSOperation新增到一個動態陣列當中

internal就是一個內部類,指代的就是NSOperationQueue,這裡也是一個KVO的手動通知,進行operations,與operationCount的改變通知。

這裡lock是NSRecursiveLock(遞迴鎖),原因我猜測是因為遞迴鎖的特性是可以被同一執行緒多次請求,而不會引起死鎖。同一執行緒的多次addOperation操做情況還是很多的。

每一次屬性的變化,都伴隨著其他屬性的改變

其實在maxConcurrentOperationCount和suspended的setter方法裡面都會呼叫_execute方法,以及在其他屬性如operationCount、operations、值發生變化的時候都會呼叫它。

那麼_execute究竟是什麼?

整個原始碼都拿上來

從原始碼中可以看到,根據isConcurrent分為直接執行,和非直接執行,isConcurrent為YES的話可以直接執行start操作,但是如果isConcurrent為NO,那麼這裡使用detachNewThreadSelector來建立新的執行緒去執行start。

總結下來:

  • 所有的執行緒都很忙,並且沒有達到threadCount的最大值的時候會建立新的執行緒,這代表queue並不是一個執行緒,也有可能有幾個
  • _execute就是一個執行佇列,依次將等待佇列裡面的所有operation進行start。

其實對於start函式來說的話,一個NSOperation並沒有新建立一條執行緒,依然操作在[NSThread currentThread]中,感興趣可以去做一下測試。從原始碼中也是可以看出來的,

總結

整個過程伴隨著很多屬性的變化,同步這些屬性,KVO在其中起著舉足輕重的作用,通過原始碼也可以發現,NSOperationQueue對NSOperation的處理分為併發和非併發的情況。如果不想採用非併發的形式,我們可以直接自定義子類化,在NSOperationQueue中新增,並且管理就可以了,功能類似執行緒池的用法。

但是如果想要自定義的NSOperation是併發的僅僅是重寫isExecuting、isFinished、isConcurrent、isAsynchronous 這四個方法,isAsynchronous反回YES就可以了嗎?

從原始碼中我們可以看到,NSOperation的start依然使用的[NSThread currentThread]。所以依然需要自己建立,例如:

現在來思考下,也就明白了為什麼NSOperationQueue要有兩種處理方式了,如果NSOperation支援併發,然後NSOperationQueue在為其分配執行緒,那就是執行緒裡面又跑了一條執行緒,這樣就很尷尬了,通過isConcurrent可以避免這種現象。

通常在大多數時候我們並不會直接去使用自定義的 NSOperation ,如果操作不復雜,可以直接使用 NSInvocationOperation 和 NSBlockOperation 這兩個子類。

如果真的需要使用多執行緒,通常都會用 NSOperationQueue來處理就可以了。

這裡也是僅僅簡單的探索了一下,上面的原始碼是封裝的NSThread,但是Apple的實現可能封裝的不是NSThread,因為斷點後並沒有看到跟NSThread相關的東西,還是有很多細節需要去推敲。

最後

我相信GNU的Foundation與Apple的Foundation的實現還是有一些相似處的,以上就是一些對應的猜想,但是有一些地方還沒有驗證

例如:原始碼中看出一個佇列裡對於非併發操作最多允許8個執行緒,但是我自己試了試,貌似不是這個樣子。可能是我的方法不對

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

NSOperation, NSOperationQueue 原理探析 NSOperation, NSOperationQueue 原理探析

相關文章