我翻遍了苹果的iBook,找不到任何关于它的定义:
有人能解释一下dispatch_after的结构吗?
dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)
我翻遍了苹果的iBook,找不到任何关于它的定义:
有人能解释一下dispatch_after的结构吗?
dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)
当前回答
在Swift 3.0中
调度队列
DispatchQueue(label: "test").async {
//long running Background Task
for obj in 0...1000 {
print("async \(obj)")
}
// UI update in main queue
DispatchQueue.main.async(execute: {
print("UI update on main queue")
})
}
DispatchQueue(label: "m").sync {
//long running Background Task
for obj in 0...1000 {
print("sync \(obj)")
}
// UI update in main queue
DispatchQueue.main.sync(execute: {
print("UI update on main queue")
})
}
5秒后调度
DispatchQueue.main.after(when: DispatchTime.now() + 5) {
print("Dispatch after 5 sec")
}
其他回答
更清晰的结构概念:
dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)
dispatch_time_t为UInt64。dispatch_queue_t实际上是一个NSObject的类型别名,但是你应该使用你熟悉的GCD方法来获取队列。该区块是一个快速关闭。具体来说,dispatch_block_t定义为()-> Void,相当于()->()。
使用示例:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
print("test")
}
编辑:
我推荐使用@matt的延时函数。
编辑2:
在Swift 3中,GCD将会有新的包装器。请看这里:https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md
原来的例子在Swift 3中是这样写的:
let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
print("test")
}
注意,你可以将deadlineTime声明写为DispatchTime.now() + 1.0,并得到相同的结果,因为+操作符被重写如下(与-类似):
func +(time: DispatchTime, seconds: Double) -> DispatchTime . func +(time: DispatchTime, seconds: Double func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime . func +(time: DispatchWalltime, interval: DispatchTimeInterval
这意味着如果您不使用DispatchTimeInterval enum,而只是写一个数字,则假定您使用的是秒。
Apple为Objective-C提供了dispatch_after代码段:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#code to be executed after a specified delay#>
});
以下是移植到Swift 3的相同代码片段:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + <#delayInSeconds#>) {
<#code to be executed after a specified delay#>
}
Swift 4有一个很短的方法来做到这一点:
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
// Your stuff here
print("hello")
}
在Swift 3.0中
调度队列
DispatchQueue(label: "test").async {
//long running Background Task
for obj in 0...1000 {
print("async \(obj)")
}
// UI update in main queue
DispatchQueue.main.async(execute: {
print("UI update on main queue")
})
}
DispatchQueue(label: "m").sync {
//long running Background Task
for obj in 0...1000 {
print("sync \(obj)")
}
// UI update in main queue
DispatchQueue.main.sync(execute: {
print("UI update on main queue")
})
}
5秒后调度
DispatchQueue.main.after(when: DispatchTime.now() + 5) {
print("Dispatch after 5 sec")
}
保留当前队列!
除了很好地回答这个问题之外,您还可以考虑保留当前队列以防止不必要的主队列操作(例如,当您试图延迟一些异步操作时)。
func after(_ delay: TimeInterval,
perform block: @escaping ()->(),
on queue: DispatchQueue = OperationQueue.current?.underlyingQueue ?? .main) { // So this `queue` preserves the current queue and defaulted to the `main`. Also the caller can pass in the desired queue explicitly
queue.asyncAfter(deadline: .now() + delay, execute: block)
}
用法:
after(3) {
// will be executed on the caller's queue
print(Date())
}