iOS延时


iOS延时

========================

今天我使用了这样一种延时,目的是等待文件下载完,返回与文件相关的数据,我试了各种多线程,后面发现这种延时有阻塞的味道,能有效地防止函数提前返回数据

while true {
    if let compiledModelURL = try? MLModel.compileModel(at: url) {
    } else {
        Thread.sleep(forTimeInterval: 2)
        continue
    }
    break
}

这种延时不能起到阻塞作用,也不能防止函数提前返回,但是它可以等待一定时间后执行某种操作。

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
    let view = UIViewController.getCurrentViewController()?.view
    view?.hideToastActivity()
    view?.hideAllToasts()
}

下面是网上看到的一些延时

// 1.perform(必须在主线程中执行)
self.perform(#selector(delayExecution), with: nil, afterDelay: 3)
// 取消
NSObject.cancelPreviousPerformRequests(withTarget: self)

// 2.timer(必须在主线程中执行)
Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(delayExecution), userInfo: nil, repeats: false)

// 3.Thread (在主线程会卡主界面)
Thread.sleep(forTimeInterval: 3)
self.delayExecution()

// 4.GCD 主线程/子线程
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
    self.delayExecution()
}

DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
    self.delayExecution()
}

延时执行

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)
}

倒计时

/// 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()
    
}

文章作者: 张赛东
文章链接: https://zsd.name
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张赛东 !
评论
  目录