美文网首页
dispatch_after 取消操作

dispatch_after 取消操作

作者: 乡下秋草 | 来源:发表于2020-12-07 21:09 被阅读0次

    iOS并没有提供官方的dispatch_after 的取消方法,但可以通过block封装完成需求。

    代码来自某不知名大神,注释按自己理解写的。

    import UIKit
    
    class HomeViewController: UIViewController {
    
        //原理:通过将操作block封装两层,定时器时间到达之后,执行第一层,并且立即执行第二层。如果想要取消第二层,则将第二层的代码块置为nil
        typealias Task = (_ cancel : Bool) -> ()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.orange
            let task = delay(3) {
                print("3秒后执行")
            }
            sleep(1)
            cancel(task)
        }
        
        @discardableResult
        func delay(_ time:TimeInterval, task:@escaping () -> ()) -> Task? {
            //定义了一个延迟函数,time秒之后调用block
            func dispatch_later(_ block:@escaping () -> ()) {
                DispatchQueue.main.asyncAfter(
                    deadline: DispatchTime.now() + Double(Int64(time * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC),
                    execute: block)
            }
            
            //将task block赋值给closure
            var closure: (() -> Void)? = task
            var result: Task?
            // Task 代码块的实现,别处通过delayedClosure(bool)调用此函数
            let delayedClosure: Task = { cancel in
                //将closure赋值给internalClosure
                if let internalClosure = closure {
                    //如果传过来的值为false,则说明不取消,立马执行internalClosure,也即closure,
                    //也即task
                    if (cancel == false){
                        //此处将立即执行,传过来的代码块
                        DispatchQueue.main.async(execute: internalClosure)
                    }
                }
                //如果传过来的值为true,则将代码块内容为nil,result为nil
                closure = nil
                result = nil
            }
            result = delayedClosure
            //此处调用开始的dispatch_later函数,当执行完成之后调用delayedClosure(false)
            dispatch_later {
                print("还是执行了")
                if let delayedClosure = result {
                    delayedClosure(false)
                }
            }
            
            return result
        }
        
        func cancel(_ task:Task?) {
            task?(true)
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:dispatch_after 取消操作

          本文链接:https://www.haomeiwen.com/subject/ywatgktx.html