swift多线程-自定义异步Operation

2,998 阅读1分钟

本篇内容多线程相关

一.自定义需要的工作

  • 需要重写的属性
  • 利用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()
    }