NSOperation 和 GCD 都是iOS下多線程編程相關(guān)的技術(shù),NSOperation 是在iOS2之后引入的脯丝,GCD稍微晚點拔莱,它是在iOS4和OS X 10.6之后引入的卷中。因為這兩項技術(shù)都是用來做多線程相關(guān)的工作政恍,所以很多程序員在使用的時候不知道如何選擇。這篇文章的主要內(nèi)容就是介紹如何在這兩項技術(shù)之間做選擇鹃操。
在介紹如何選擇這兩種API之前韭寸,我準(zhǔn)備先介紹下NSOperation和GCD的主要區(qū)別。
主要區(qū)別
NSOperation是對GCD的一個封裝(因為NSOperation是在GCD之前出現(xiàn)的荆隘,所以在GCD出現(xiàn)之前恩伺,NSOperation并不是對GCD的封裝),以objective-c面向?qū)ο蟮姆绞教峁〢PI椰拒,這就意味著晶渠,如果你用NSOperation,其實底層還是用的GCD燃观。
GCD是一套C的API褒脯,相對底層一點。所以缆毁,NSOperation相對效率更低番川。因為實例化一個NSOperation對象、以及釋放一個NSOperation都是需要代價的脊框。
NSOperation的優(yōu)點
雖然NSOperation是建立在GCD之上的API颁督,但是NSOperation有幾個功能是GCD無法提供的。
- Dependencies (依賴)
NSOperation支持依賴浇雹,比如說有兩個operation A和B沉御,A要在B執(zhí)行完之后執(zhí)行,那么可以他們提供一個依賴關(guān)系即可昭灵。
- Observable
NSOperation和NSOperationQueue有許多屬性是可以通過kvo來觀察吠裆,這樣的話你可以實時監(jiān)測operation和operation queue的狀態(tài)伐谈。
- Pause,Cancel试疙,Resume
operation可以暫停(pause)诵棵、喚醒(resumed),以及取消(canceled),GCD就不存在這種控制的API效斑,所以非春,NSOperation可以更靈活的控制operation的生命周期。
- Control
使用NSOperationQueue還有其他的好處缓屠,比如說可以指定同時最大并發(fā)數(shù)。
如何選擇NSOperation和GCD
通常情況下护侮,Apple建議開發(fā)者選擇高層的API敌完,如果我們遵守這個原則,那么應(yīng)該選用NSOperation比較好羊初。
選用高層的API有一個好處滨溉,就是每次iOS系統(tǒng)的更新,Apple都會調(diào)整或者一些framework或者library长赞,從而使系統(tǒng)更加優(yōu)秀晦攒,這樣的更新往往會涉及底層的API,所以得哆,如果我們使用的高層的API脯颜,就算我們沒有改變我們使用的API,我們也可以享受蘋果對底層代碼的優(yōu)化帶來的好處贩据,如果我們使用的底層的API栋操,那么我們的應(yīng)用也必須進(jìn)行相應(yīng)的升級才能享受這種變化。
基于此是不是就是說完全使用NSOperation饱亮,避免使用GCD呢矾芙?實際上也不是這樣的,我們需要根據(jù)實際的情況使用NSOperation或者GCD近上,亦或者同時使用這兩者剔宪。
- 什么時候使用NSOperation
NSOperation非常適合封裝功能明確的功能塊,比如說壹无,你可以用NSOperation的子類封裝用戶登錄的模塊葱绒。
依賴也是NSOperation中的一個非常有用的特點,當(dāng)你的功能模塊需要一個特定的順序的時候格遭,那么NSOperation是最好選擇哈街。
- 什么時候使用GCD
如果你的需求僅僅是把一個代碼塊調(diào)度到一個串行或者并發(fā)的隊列里,那么GCD是個好的選擇拒迅,因為這樣不需要創(chuàng)建NSOperation的子類骚秦,而且使用GCD相關(guān)的代碼都在一塊她倘,代碼的可讀性要高。比如下面的代碼:
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
// Process Response
...
dispatch_async(dispatch_get_main_queue(), { () -> Void in
// Update User Interface
...
})
})
- NSBlockOperation
開發(fā)者不能直接使用NSOperation作箍,也就是必須要使用它的子類硬梁。Foundaation框架已經(jīng)提供了一個可以直接使用的子類NSBlockOperation,使用方式如下:
let operation = NSBlockOperation(block: { () -> Void in
// Do Something
...
})
operationQueue.addOperation(operation)
總結(jié)
本文介紹了NSOperation和GCD的區(qū)別胞得,在使用的時候盡量使用NSOperation荧止,因為這樣可以進(jìn)行很好的控制。當(dāng)然阶剑,如果是很簡單的調(diào)度跃巡,直接使用GCD是一種更好的選擇。