iOS延时

iOS延时

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

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

1
2
3
4
5
6
7
8
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
// 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()
}

延时执行

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
/// 代码延迟运行
///
/// - 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)
}

倒计时

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

}

定时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/// 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()

}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!