CNLiveTimer.swift 3.15 KB
//
//  CNLiveTimer.swift
//  metaCode
//
//  Created by zx on 2023/11/29.
//

import Foundation

//坑点 最初使用FLT_MIN为永远执行时间判断 后来发现bug 即FLT_MIN==0而不是float的最小值
//永远执行时间
let kBKTimerRepeatsTime:CGFloat = -999999
let kMinTimeInterval:CGFloat = 0.000001

typealias timerHandlerBlock = (_ timer:DispatchSourceTimer,_ lastTime:CGFloat) -> Void

class CNLiveTimer:NSObject{
    
    // MARK: - 创建定时器方法
    /**
     初始化定时器

     @param timeInterval 时间间隔 (最多6位小数 即0.000001)
     @param totalTime 执行总时间  totalTime==kBKTimerRepeatsTime 时无限执行
     @param handler 回调
     @return 定时器
     */
    class func bk_setupTimerWithTimeInterval(timeInterval:TimeInterval,totalTime:CGFloat,handler:@escaping timerHandlerBlock)->DispatchSourceTimer{
        let serialQueue = DispatchQueue.init(label: "CNLiveGCDTimer", target: DispatchQueue.global())
        var timer = DispatchSource.makeTimerSource()
        var temp_timeInterval = timeInterval
        if temp_timeInterval < kMinTimeInterval{
            temp_timeInterval = kMinTimeInterval
        }
        var lastTime = totalTime
        timer.schedule(deadline: .now()+temp_timeInterval, repeating: timeInterval, leeway: DispatchTimeInterval.never)
        timer.setEventHandler {
            
            if (totalTime != kBKTimerRepeatsTime) {
                lastTime = lastTime - temp_timeInterval
                
                //保留6位小数 取出整数和小数
                let lastTimeStr = String(format: "%.6f", lastTime)
                let array = lastTimeStr.components(separatedBy: ".")
                //检测剩余时间是否为kMinTimeInterval 即0.000000
                var flag = true
                let integer = array.first
                if integer == "0"{
                    //判断整数是否为0
                    let decimal = array.last
                    for i in 0..<(decimal?.count ?? 0) {
                        let range_string = decimal?.subString(start: i, length: 1)
                        if range_string == "0"{
                            //判断小数所有位数是否为0
                            flag = false
                            break
                        }
                    }
                }else{
                    flag = false
                }
                if flag{
                    lastTime = 0
                    self.bk_removeTimer(timer: timer)
                }else{
                    if (lastTime <= 0) {
                        lastTime = 0
                        self.bk_removeTimer(timer: timer)
                    }
                }
            }
            DispatchQueue.main.async {
                handler(timer,lastTime)
            }
        }
        timer.resume()
        return timer
    }

    // MARK: - 销毁定时器方法
    /**
     删除定时器
     */
    class func bk_removeTimer(timer:DispatchSourceTimer){
        timer.cancel()
        //    dispatch_source_cancel(timer);//在在创建多次,并且瞬间删除全部时有可能崩溃 所以用dispatch_cancel(timer)替代
//        timer = nil
    }
}