iOS延时
========================
今天我使用了这样一种延时,目的是等待文件下载完,返回与文件相关的数据,我试了各种多线程,后面发现这种延时有阻塞的味道,能有效地防止函数提前返回数据
| while true { if let compiledModelURL = try? MLModel.compileModel(at: url) { } else { Thread.sleep(forTimeInterval: 2) continue } break }
|
这种延时不能起到阻塞作用,也不能防止函数提前返回,但是它可以等待一定时间后执行某种操作。
1 2 3 4 5
| DispatchQueue.main.asyncAfter(deadline: .now() + 3) { let view = UIViewController.getCurrentViewController()?.view view?.hideToastActivity() view?.hideAllToasts() }
|
下面是网上看到的一些延时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| self.perform(#selector(delayExecution), with: nil, afterDelay: 3)
NSObject.cancelPreviousPerformRequests(withTarget: self)
Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(delayExecution), userInfo: nil, repeats: false)
Thread.sleep(forTimeInterval: 3) self.delayExecution()
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { self.delayExecution() }
DispatchQueue.global().asyncAfter(deadline: .now() + 3) { self.delayExecution() }
|
延时执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| typealias Task = (_ cancel: Bool) -> Void
@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) }
|
倒计时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
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() }
|
定时器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
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() }
|