美文网首页Swift开发指导
Swift 延时执行、倒计时、定时器

Swift 延时执行、倒计时、定时器

作者: KaKaLaaa | 来源:发表于2020-09-02 19:02 被阅读0次

    延时执行

    代码块的延时运行我们很常见也很常用,不少封装都不错也易于使用。在GCD的基础上我们可以将代码延时运行封装得更好用一些,再加上可以取消延时的功能,我们通过捕获一个cancel标识变量来实现delay call的取消,下面是完整的封装方法,可以尝试调用看看~

        typealias Task = (_ cancel: Bool) -> Void
        /// 代码延迟运行
        ///
        /// - Parameters:
        ///   - delayTime: 延时时间。比如:.seconds(5)、.milliseconds(500)
        ///   - qosClass: 要使用的全局QOS类(默认为 nil,表示主线程)
        ///   - task: 延迟运行的代码
        /// - Returns: Task?
        @discardableResult
        static func bk_delay(by delayTime: TimeInterval, qosClass: DispatchQoS.QoSClass? = nil, _ task: @escaping () -> Void) -> Task? {
            
            func dispatch_later(block: @escaping () -> Void) {
                let dispatchQueue = qosClass != nil ? DispatchQueue.global(qos: qosClass!) : .main
                dispatchQueue.asyncAfter(deadline: .now() + delayTime, execute: block)
            }
            
            var closure: (() -> Void)? = task
            var result: Task?
            
            let delayedClosure: Task = { cancel in
                if let internalClosure = closure {
                    if !cancel {
                        DispatchQueue.main.async(execute: internalClosure)
                    }
                }
                closure = nil
                result = nil
            }
            
            result = delayedClosure
            
            dispatch_later {
                if let delayedClosure = result {
                    delayedClosure(false)
                }
            }
            
            return result
            
        }
    
        /// 取消代码延时运行
        func delayCancel(_ task: Task?) {
            task?(true)
        }
    

    使用的时候就很简单啦~如下调用:

    delay(by: 3) { print("3秒后执行") }
    

    想要取消的话,我们可以先保留一个对Task的引用,然后调用delayCancel:

    let task = delay(by: 2) { print("2秒后执行") }
    // 不执行了,还是取消掉吧
    delayCancel(task)
    

    倒计时

    这里分享的也是GCD的倒计时封装,比起Timer项目中要根据自身情况合理使用不同计时方法。

        /// GCD定时器倒计时
        ///
        /// - Parameters:
        ///   - timeInterval: 间隔时间
        ///   - repeatCount: 重复次数
        ///   - handler: 循环事件,闭包参数: 1.timer 2.剩余执行次数
        func dispatchTimer(timeInterval: Double, repeatCount: Int, handler: @escaping (DispatchSourceTimer?, Int) -> Void) {
            
            if repeatCount <= 0 {
                return
            }
            let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
            var count = repeatCount
            timer.schedule(deadline: .now(), repeating: timeInterval)
            timer.setEventHandler {
                count -= 1
                DispatchQueue.main.async {
                    handler(timer, count)
                }
                if count == 0 {
                    timer.cancel()
                }
            }
            timer.resume()
            
        }
    

    定时器

    直接上代码啦~

        /// GCD实现定时器
        ///
        /// - Parameters:
        ///   - timeInterval: 间隔时间
        ///   - handler: 事件
        ///   - needRepeat: 是否重复
        func dispatchTimer(timeInterval: Double, handler: @escaping (DispatchSourceTimer?) -> Void, needRepeat: Bool) {
            
            let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
            timer.schedule(deadline: .now(), repeating: timeInterval)
            timer.setEventHandler {
                DispatchQueue.main.async {
                    if needRepeat {
                        handler(timer)
                    } else {
                        timer.cancel()
                        handler(nil)
                    }
                }
            }
            timer.resume()
            
        }
    

    总之,GCD的使用方法多种多样,多多练习尝试使用~

    联系方式:kim77895pl@gmail.com
    Kim 写于2020.9.2,希望文章能对你有所帮助。

    相关文章

      网友评论

        本文标题:Swift 延时执行、倒计时、定时器

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