Operation的簡單使用
阿新 • • 發佈:2019-12-25
當前環境: Xcode10.0 Swift4.2 iOS SDK 12.1
Demo下載: github.com/zColdWater/…
前言
之前的工作中一直沒有怎麼接觸Operation來管理多執行緒,直到最近在做專案的時候需要使用多執行緒佇列等複雜的任務管理,我開始逐步接觸Operation和使用它帶給我的方便。
在使用過程中我也在比對,什麼時候應該用GCD合適 什麼時候用Operation合適. 因為之前對GCD使用比較多一些所以有些問題能用GCD就用GCD完全沒有考慮Operation,直到最近使用Operation帶來效益才覺得,有些情況更適合使用Operation來處理。
非同步Operation
/// 如果是需要非同步執行程式碼
/// 需要覆蓋: 1.isAsynchronous(預設是false,需要修改成true. 僅是給外界宣告自己是 同步操作還是非同步操作,沒有什麼特殊功能。)
/// 需要覆蓋: 2.isExecuting 當開始任務 設定成 Ture,執行完成後 設定成 False
/// 需要覆蓋: 3.isFinished 當開始任務 設定成 False,執行完成後 設定成 True
/// 需要覆蓋: 4.start 非同步程式碼 編寫的位置
/// 注意⚠️: 需要手動的來控制Operation狀態,Operation才能結束。
class AsyncOperation: Operation {
override init() {}
var result: String = ""
var taskName: String = ""
override var isAsynchronous: Bool { return true }
private let stateLock = NSLock()
// 一定要寫KVO 否則無法更改狀態
// willChangeValue && didChangeValue
private var _executing: Bool = false
override private(set) var isExecuting: Bool {
get {
return stateLock.withCriticalScope { _executing }
}
set {
willChangeValue(forKey: "isExecuting")
stateLock.withCriticalScope {
if _executing != newValue {
_executing = newValue
}
}
didChangeValue(forKey: "isExecuting")
}
}
// 一定要寫KVO 否則無法更改狀態
// willChangeValue && didChangeValue
private var _finished: Bool = false
override private(set) var isFinished: Bool {
get {
return stateLock.withCriticalScope { _finished }
}
set {
willChangeValue(forKey: "isFinished")
stateLock.withCriticalScope {
if _finished != newValue {
_finished = newValue
}
}
didChangeValue(forKey: "isFinished")
}
}
override func start() {
launchOperation()
let queue: DispatchQueue = DispatchQueue(label: "serialQueue")
queue.async {
// 當前執行緒睡10s
sleep(10)
// 結果賦值
if self.taskName == "任務1" {
self.result = "I"
}
if self.taskName == "任務2" {
self.result = "Love"
}
if self.taskName == "任務3" {
self.result = "U"
}
// 改變Operation狀態告訴外界,我執行完了,結束了。
self.completeOperation()
}
}
func completeOperation() {
isExecuting = false
isFinished = true
}
func launchOperation() {
isExecuting = true
isFinished = false
}
}
extension NSLock {
func withCriticalScope<T>(block: () -> T) -> T {
lock()
let value = block()
unlock()
return value
}
}
複製程式碼