在上一篇例子中我们实现的是Operation是同步的,本篇将着重介绍异步实现。
Operation的状态是完全由底层自动管理的只读属性,正常情况下,Operation
在结束main
函数的运行时就会把状态切换成isFinished
。
但是如果我们在Operation
的main
函数中执行了异步操作,Operation
的自带机制就无法正常切换状态。main
结束的时候我们的异步可能还在正常运行中。
AsyncOperation
为了方便读写任务状态,我们给AsyncOperation
重新写一个状态属性
Operation类的状态切换用的是KVO
通知,所以我们给自定义的状态一个计算属性keyPath
来匹配原基类的状
class AsyncOperation: Operation {
// Create state management
enum State: String {
case ready, executing, finished
fileprivate var keyPath: String {
return "is\(rawValue.capitalized)"
}
}
// Override properties
var state = State.ready {
willSet {
willChangeValue(forKey: newValue.keyPath)
willChangeValue(forKey: state.keyPath)
} didSet {
didChangeValue(forKey: oldValue.keyPath)
didChangeValue(forKey: state.keyPath)
}
}
override var isReady: Bool {
return super.isReady && state == .ready // 一定要先检测isReady 因为它是受系统任务计划程序控制的
}
override var isExecuting: Bool {
return state == .executing
}
override var isFinished: Bool {
return state == .finished
}
override var isAsynchronous: Bool {
return true
}
// Override start
override func start() {
// 官方文档说明在重写start()的时候不可以调用super
if isCancelled {
state = .finished
return
}
main()
state = .executing // 因为异步任务还在进行中
}
}
使用
class ExampleAsyncOperation: AsyncOperation {
override func main() {
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 2)
self.state = .finished
}
}
}
系列文章链接