最近在研究NSOperation+NSOperationQueue vs GCD的部份; 本篇是關於NSOperation + NSOperationQueue的一些介紹
關於NSOperation, 基本上是用來操作/執行一個單一的任務, 如果你的任務不複雜, 其實可以使用NSInvocationOperation
或是NSBlockOperation
直接使用;關於NSOperation又可以分成並發(concurrent,
並連)或非並發(non-concurrent, 串連), 這篇會稍微介紹一下在不使用NSOperationQueue
如何成為一個concurrent
(asynchrouons
)的operation.
這篇會提到的內容
- 如何建立Subclass of Operation
- 建立concurrent Operation
- Operation在Queue的用法
可能還會提到一點點的NSThread
&NSRunLoop
如何建立Subclass of NSOperation
因為NSOpertaion是一個抽象的Class, 所以在繼承的時候, 會需要去實作一些內容; 要實作的內容又因為Operation是concurrent或是non-concurrent有所不同.
non-concurrent
建立non-concurrent的operation比較簡單, 只要在建立的class去實作下面的method的就可以了
non-concurrent operation need implement method
1
|
|
在這個method中完成你要做的事情, 就是一個non-concurrent operation了.
concurrent
在實作一個concurrent operation相對來說複雜了一點, 你最少需要實作(override)下列幾個methods.
concurrent operation need implement methods
1 2 3 4 |
|
其中下面兩mehtod改變數值時個需要實作KVO notifications.
- isExecuting
- isFinished
在start
中, 你必須要去實現異步(asynchronous)的方式,
你會需要產生一個thread讓operation的任務執行在這個thread中; 這邊同時還要注意的是, 不可以在這邊使用[super
start]
; 以及在執行之前是否這個Operation是否已經被Cancel(isFinished)的狀況.
建立concurrent Operation
在上面我們已經了解了建立一個 Subclass of Operation需要實作哪些內容; 接下來直接進入如何建立自己的, 那麼我們開始建立一個新的ClassMyOperation
並繼承NSOperation
,
並且有一個建立instance的Mehtod, 可以傳入一個block action. 下面我們先大致定義一些內容, 方便之後的實作.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
在.m中, 建立了一個列舉來代表Operation的執行狀態, 接下來我們覆寫幾個應該要實作的method
Override Methods
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
在上面有提到, 如果要讓Operation實現Concurrent我們就必須在在start
中去建立一個Thread,
並且讓他的任務在這個Thread中執行; 因此我們將建立一個singleton thread來讓MyOperation使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
上面有兩個method, 其中keepThreadAlive
就如同Method的名字一樣,
是為了要讓Thread可以持續的運作, 不會在還沒做完事情, thread就結束了. 裡面的作法就是給他一個無限的loop, 去執行NSRunLoop
的run
mehtod.
讓這個thread成為NSRunLoop的一個input source
.
這樣子的作法會讓這個thread, 一直存活直到user把app關閉才會結束.
接下來我們回到start
來
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
到這邊基本上已經完成concurrent operation的實作了, 我們先來測試一下跑起來的情況; 這邊我用一個BlockOperation跟MyOperation一起執行, 我把 MyOperation放在blockOperation前執行~
test MyOperation
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
從上圖顯示的Log, 兩個Operation第一個Log的時間是相同的, 所以不算上延遲的話 … 應該已經達到我們想要的asynchronous效果, 那麼接下來在來看看在start中我們有使用到[self
isReady]
, 另外在operationDidStart中也有去判斷operation是否已經cancel的狀態, 所以我們會需要對isReady
以及cancel
這兩個method做一些調整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
到這邊我們把需要用到的method都有實作到了, 不過前面我們有提到isExecuting
、isFinished
是需要實作KVO
Nofifications
的, 在文件中你可以看到需要generate KVO notifications的property大該有下列幾個
- isCancelled- read-only property
- isConcurrent - read-only property
- isExecuting- read-only property
- isFinished- read-only property
- isReady- read-only property
- dependencies - read-only property
- queuePriority - readable and writable property
- completionBlock - readable and writable property
其中粗體的部份是在MyOperation會變動的, 所以我們必須在變動的時候送出KVO Notification, 因此我們再稍微調整一下, 在有修改到state幾個地方跟cancel都加上動作
add kvo notifications
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
這樣, 就完成了一個簡易的Operation了~ 當然在不同的情況之下還是有一些部分需要做調整, 例如使用OperationQueue的時候, 你為Operation加上dependent
operation
, 就必須要讓isReady returnNO
,
否則queue可能就會判斷operation isReady=YES, 就直接去執行, 這樣造成結果或執行上的錯誤.
Operation在Queue的用法
在前面有講接一些該如何去實作一個Operation; 當然提到Operation通常都不會忘掉OperationQueue, 使用Queue, 除了可以讓non-concurrent operation達到concurrent的效果外, 也可以讓Operation去等待某些Operation完成後再去執行(替operation加上dependent
operation
), 而且比起每次都自行去建立Thread
並且在用完後自行回收,
OperationQueue使用起來更加的方便更有效率.
在使用的時候, 要讓non-concurrent operation在queue中可以以concurrent的方式去執行, 你必須要建立一個NSOperationQueue實體, 如果使用[NSOperationQueue
mainQueue]
所取得的queue, 除非operation有特別處理過, 不然都會在main
thread
中執行, 不過依然會等待上一個operation完成後才會去執行; 以下面的範例, 我們來看看輸出的結果會如何:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
從上面的結果, 你可以看到queue幫我們建立了三個thread分別給operation01、02跟03使用(有時候02跟03可能會出現公用一個thread的狀況), 你並不需要去特別管理thread, queue會自己幫你完成; 在上面的程式碼中, 我設定了queue一次最多可以執行五個operation, 然後operation03必須等operation02完成後, 才會接著執行, 因此圖片中顯示的結果是operation01跟02是一起執行, 接著operation03才執行.
那如果這時候把上面使用的MyOperation會發生什麼事勒, 我們來試試看~ 下面改一下程式碼
add MyOperation to the queue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
基本上bopt01、02跟myopt01(myopt02)會是concurrent, 而myopt01跟02之間則是non-concurrent必須要其中一個完成後才會繼續執行(共用同一個thread).
那麼, 有沒有辦法讓Operation(ex:MyOperation)自己執行的時候是concurrent, 然後在queue中執行的時候也是concurrent的方式?
答案我想是有的, 多一個Mehtodasychronous
跟變數去判斷是不是asynchronous啟動opertaion,
是的話就給他一個thread去執行任務, 如果直接執行start
, 就會是non-concurrent
operation; 這樣在使用queue的時候, 因為queue會直接去執行start
,
就可以直接幫operation建立一個thread達到concurrent的目的. (isConcurrent = YES or NO, 好像不是主要的判斷方式)
最後
打完後發現感覺是打給自己看的XD, 都是程式碼~; 不過也把它留存當記錄囉, 如果有幫助到其他人也很棒. 有看到的人如果發現錯誤也麻煩幫忙指正一下, 感謝.
最後附上參考網址跟一些stackoverflow的內容:
相关推荐
ios 多线程NSoperation
Demo讲解了同步和异步的NSOperation的示例,更多的参见我的博客
NSOperation的基本使用 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后...
NSInvocationOperationViewController: NSOperation 的子类 NSInvocationOperation 线程的基本使用 NSBlockOperationViewController: NSOperation 的子类 NSBlockOperation 线程的基本使用 ...
NSOperation NSOperationQueue demo 项目讲述了 NSOperation 和 NSOperationQueue 怎么使用。适合学习
多线程加载图片
一、NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个...
一个NSOpration的例子,转载自raywenderlich
OC-NSOperation异步线程下载图片
Objective-C的NSOperation多线程类基本使用指南剖析.pdfObjective-C的NSOperation多线程类基本使用指南剖析.pdfObjective-C的NSOperation多线程类基本使用指南剖析.pdfObjective-C的NSOperation多线程类基本使用指南...
iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD
iOS-多线程之NSOperation - iOS知识库1
NSOperation和NSOperationQueue:其实出现得比GCD更早,但是GCD出现以后苹果在GCD的基础上对NSOperation进行了重写,使其对象化,符合了大众开发者的习惯。作为更高层的技术,NSOperation在处理依赖关系、控制各种...
AFHTTPSessionOperation, 添加到 `AFHTTPSessionManager`的请求的`NSOperation` 子类 AFHTTPSessionOperation简介AFHTTPSessionOperation 是添加到 AFNetworking AFHTTPSessionManager的HTTP请求的NSOperation 子类...
iOS开发 - 第04篇 - 网络 - 01 - NSOperation & 网络基础,对应博客地址:http://blog.csdn.net/nsryan
主要介绍了iOS多线程应用开发中自定义NSOperation类的实例解析,代码基于传统的Objective-C,需要的朋友可以参考下
想在开发过程中,学习使用线程的朋友可以下来看看。里面涵盖了 几乎所有线程使用的类型。而且对这几种 类进行了很细致的解释。包括 定义,功能,和其他的比较。很不错的