本篇内容多线程相关
一.自定义需要的工作
- 需要重写的属性
- 利用KVO来通知Operation的isExecuting(是否正在进行中),以及isFinished(是否已经完成)
- 重写start方法,开辟新的线程执行需要的耗时工作。注意:不能调用父类的start方法。
- 重写cancle方法
二.具体实现
1.需要重写的属性
override var isExecuting: Bool{
return _executing
}
override var isFinished: Bool{
return _finished
}
override var isAsynchronous: Bool{
return true
}
2.KVO通知部分
//指定用于记录任务是否执行
private var _executing:Bool = false{
//kvo isExecuting
willSet{
willChangeValue(forKey: ModifyState.isExecuting.rawValue)
}
didSet{
didChangeValue(forKey: ModifyState.isExecuting.rawValue)
}
}
//指定用于记录任务是否完成
private var _finished:Bool = false{
//kvo isFinished
willSet{
willChangeValue(forKey: ModifyState.isFinished.rawValue)
}
didSet{
didChangeValue(forKey: ModifyState.isFinished.rawValue)
}
}
/// 修改状态枚举(重写状态的字段标识)
private enum ModifyState: String{
case isExecuting = "isExecuting"
case isFinished = "isFinished"
}
3.重写start方法
因为Operation有cancel方法来取消操作,而且我们并不知道在何时取消,所以我们需要在几个地方注意是否取消了操作.
- 进入start方法时
- 执行耗时的任务后
override func start() {
//检测取消状态
if isCancelled{
done()
return
}
//修改状态->执行
_executing = true
//开启任务->并行,完成回调测试
startTask()
}
//开启任务(模拟耗时任务)
private func startTask(){
DispatchQueue.global().async { [weak self] in
print("线程:",Thread.current)
//耗时
sleep(2)
for i in 0...2{
print("\(i)")
}
//检测状态
if self?.isCancelled ?? false{
self?.done()
return
}
//
DispatchQueue.main.async { [weak self] in
//完成
self?.completedBlock?(true)
self?.done()
}
}
}
4.重写cancle方法
cancel方法做了线程安全保护.
//重写取消
override func cancel() {
objc_sync_enter(self)
done()
objc_sync_exit(self)
}
//自定义cancel
private func done() {
super.cancel()
print("done start",isCancelled)
if(_executing) {
_finished = true
_executing = false
}
print("done end",isCancelled)
}
三.测试
代码如下:
func testCustomerOp() {
customerOp.completedBlock = { result in
print("任务完成, \(result)")
}
//customerOp.cancel()
customerOp.start()
//customerOp.cancel()
print("结束")
// sleep(6)
// customerOp.cancel()
// customerOp.start()
}