iOS --- 多線程之NSOperation

NSOperation基於GCD封裝實現的,比GCD稍慢,可設定各個操作之間的依賴關係及優先級等。相對於GCD而言,NSOperation主要會涉及到使用NSOperationQueue來調度和管理各個NSOperation對象及操作。

NSBlockOperation

let myOperation = NSBlockOperation(block: { () -> Void in
    // self.delayAction()
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        // self.updateUI()
    })
})

// 設置完成之後的block操作
myOperation.completionBlock = { () -> Void in
    // completion block
}

myOperation.addExecutionBlock({ () -> Void in
    // action
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        // update UI
    })
})

NSOperationQueue().addOperation(myOperation)

// 也可以直接使用如下方法
// myOperation.start()
// myOperation.cancel()

Dependency

操作之間可以添加依賴關係,既可以設置執行的先後順序

let myOperation1 = NSBlockOperation(block: { () -> Void in
    // operation 1
})
let myOperation2 = NSBlockOperation(block: { () -> Void in
    // operation 2
})

// 若不添加依賴關係,則兩個任務的執行順序隨機
myOperation1.addDependency(myOperation2)
// myOperation1.removeDependency(myOperation2)

// 默認是並行隊列
let myOperationQueue = NSOperationQueue()
myOperationQueue.addOperation(myOperation1)
myOperationQueue.addOperation(myOperation2)

Priority

let myOperation1 = NSBlockOperation(block: { () -> Void in
    print("myOperation1")
})
let myOperation2 = NSBlockOperation(block: { () -> Void in
    print("myOperation2")
})

// 優先級並不一定等於依賴關係,只是系統調度時候傾向而已。
// 兩次執行的順序也可能不一樣,並非強制排序。
myOperation1.queuePriority = NSOperationQueuePriority.VeryLow
myOperation2.queuePriority = NSOperationQueuePriority.VeryHigh

let myOperationQueue = NSOperationQueue()
myOperationQueue.addOperation(myOperation1)
myOperationQueue.addOperation(myOperation2)

maxConcurrentOperationCount

let myOperation1 = NSBlockOperation(block: { () -> Void in
    print("myOperation1")
})
let myOperation2 = NSBlockOperation(block: { () -> Void in
    print("myOperation2")
})

let myOperationQueue = NSOperationQueue()
// 該併發隊列中,一次只能執行一個任務,所以順序固定
myOperationQueue.maxConcurrentOperationCount = 1
myOperationQueue.addOperation(myOperation1)
myOperationQueue.addOperation(myOperation2)

cancel和suspeded

let myOperation1 = NSBlockOperation(block: { () -> Void in
    print("myOperation1")
})

let myOperationQueue = NSOperationQueue()
myOperationQueue.addOperation(myOperation1)
// myOperation1.cancel()
// myOperationQueue.cancelAllOperations()
// myOperation1.waitUntilFinished() // 會阻塞主線程
myOperationQueue.suspended = true // 只能暫停後添加的操作,已添加的不能暫停

NSOperationQueue

NSOperationQueue用來生成一個隊列,將NSOperation對象可添加進去。例如,使用NSURLConnection操作,可指定對應的operationQueue。也可用於防止出現多次重複的http請求。不過,一般網絡請求都不放在mainQueue中。

NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler: { (response: NSURLResponse?, data: NSData?, error: NSError?) -> Voin in
    // Parse request data
})

自定義任務隊列

先定義一個CSOperation的類,繼承自NSOperation,如下:

protocol CSOperationCompletionDelegate {
    func csOperationCompletion()
}

// 自定義NSOperation
class CSOperation: NSOperation {

    var delegate: CSOperationCompletionDelegate!

    override func main() {
        super.main()

        sleep(2)
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            if (self.delegate != nil) {
                self.delegate.csOperationCompletion()
            }
        })
    }
}

使用如下,將該類的對象添加到OperationQueue即可。

let csOperation = CSOperation()
csOperation.delegate = self
NSOperationQueue().addOperation(csOperation)

// 繼承CSOperationCompletionDelegate協議
func csOperationCompletion() {
    print("csOperationCompletion")
}

Demo

Demo地址: DemoMultiThread

發佈了117 篇原創文章 · 獲贊 18 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章