1. 程式人生 > >Swift版本 2.多執行緒開發 -- NSOperation的簡單使用

Swift版本 2.多執行緒開發 -- NSOperation的簡單使用

前面我們已經講完了 GCD 的基本概念以及基本使用, 現在讓我們來看看第二個多執行緒開發, NSOperation, 這個類是蘋果在 GCD 的基礎上再次開發的, 所以並不會太難.

1.基本概念

NSOperation和 GCD 不太一樣, 它不像 GCD 一樣有各種佇列, 只保留了自定義佇列和全域性佇列.

所謂的主佇列肯定就是在主執行緒中執行的, 而自定義佇列就是在後臺執行的

PS: 這裡需要注意一下, Swift 在 iOS8.1的時候, 就已經把NSInvocationOperation這個方法禁用了, 只剩下NSBlockOperation.

2.NSOperation佇列

    func demo1() {
        // 自定義佇列 - 方法一
        var block: NSBlockOperation = NSBlockOperation { () -> Void in
        println("\(NSThread.currentThread()) -- NSThread")
        }
        myQueue.addOperation(block)

        // 自定義佇列 -- 方法二
        // 新增到自定義佇列中
        // 所有自定義的佇列都在子執行緒中執行

        // 新建執行緒是有開銷的, 所以NSOperationQueue提供了一個方法
// 在設定同時併發的最大執行緒時, 如果前一個執行緒工作完成, 但還沒有銷燬, 會新建執行緒 // 應用場景: 網路開發中, 下載工作! (執行緒開銷: CPU, MEM) 電量 // 如果是3G, 開3個子執行緒 // 如果是 Wifi, 就開6個子執行緒 // 該方法使用來控制執行緒數量, 雖然也是不可控的, 但相對來講可以節省一些資源 myQueue.maxConcurrentOperationCount = 1 // 併發執行, 執行緒數量不可控 for i in 0...9 { myQueue.
addOperationWithBlock({ () -> Void in println("\(NSThread.currentThread()) i -- \(i)") }) } // 在主執行緒中執行 NSOperationQueue.mainQueue().addOperationWithBlock { () -> Void in println("\(NSThread.currentThread()) -- main") } }

NSOperation 和 GCD 不太一樣, 如果我們沒有指定最小範圍的子執行緒數量的話, 那麼就會申請多個子執行緒, 但在 NSOperation 中可以設定最大子執行緒的接近值(maxConcurrentOperationCount).

3.依賴關係

在 NSOperation 中不同的還有一種關係叫做依賴關係, 這個和 GCD 的序列佇列有些相似, 一旦我們設定好依賴關係之後, 就可以逐步依次往下執行.

    func demo2() {
        var op1 = NSBlockOperation { () -> Void in
            println("\(NSThread.currentThread()) -- 下載圖片")
        }
        var op2 = NSBlockOperation { () -> Void in
            println("\(NSThread.currentThread()) -- 修改圖片")
        }
        var op3 = NSBlockOperation { () -> Void in
            println("\(NSThread.currentThread()) -- 儲存圖片")
        }
        var op4 = NSBlockOperation { () -> Void in
            println("\(NSThread.currentThread()) -- 更新介面")
        }

        // 新增依賴關係, 只有當前一個執行緒執行完才會去執行下一個依賴的執行緒
        op2.addDependency(op1)
        op3.addDependency(op2)
        op4.addDependency(op3)

        // 新增到執行緒
        myQueue.addOperation(op1)
        myQueue.addOperation(op2)
        myQueue.addOperation(op3)

        // PS: 所有介面的更新都是在主執行緒中完成的
//        myQueue.addOperation(op4)
        NSOperationQueue.mainQueue().addOperation(op4)

    }

PS: 注意一點, 這裡的依賴關係我們需要寫的非常明確, 而且不能迴圈依賴, 否則程式就會出問題了.

4.總結

在一定的程度上, NSOperation的效能比 GCD 的要稍微差一點, 但在大多數情況下是可以忽略不計的, 如果非要使用併發, 那麼 NSOperation 是首選的工具.

但也有一些框架是使用 NSOperation 的介面, 底層卻是用 GCD 實現的, 比如 AFNetworking

好了, 這次我們就講到這裡, 下次我們繼續~~