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