我翻遍了苹果的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?#>)
当前回答
虽然不是OP的原始问题,但某些与NSTimer相关的问题已被标记为该问题的重复,因此值得在这里包含NSTimer的答案。
NSTimer vs dispatch_after
NSTimer更高级,而dispatch_after更低级。 NSTimer更容易取消。取消dispatch_after需要编写更多的代码。
用NSTimer延迟任务
创建一个NSTimer实例。
var timer = NSTimer()
以您需要的延迟启动计时器。
// invalidate the timer if there is any chance that it could have been called before
timer.invalidate()
// delay of 2 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
添加一个在延迟之后被调用的函数(使用您用于上面选择器参数的任何名称)。
func delayedAction() {
print("Delayed action has now started."
}
笔记
如果需要在操作发生之前取消该操作,只需调用timer.invalidate()。 对于重复的动作使用repeats: true。 如果你有一个不需要取消的一次性事件,那么就不需要创建计时器实例变量。以下内容就足够了: NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false) 在这里看到我更完整的回答。
其他回答
使用这段代码在2.0秒后执行一些UI相关的任务。
let delay = 2.0
let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
let mainQueue = dispatch_get_main_queue()
dispatch_after(delayInNanoSeconds, mainQueue, {
print("Some UI related task after delay")
})
Swift 3.0版本
以下闭包函数在主线程上执行一些延迟后的任务。
func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
onCompletion()
})
}
像这样调用这个函数:
performAfterDelay(delay: 4.0) {
print("test")
}
Swift 3.0 & Swift 4.0 & Swift 5.0中最简单的解决方案
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
使用
delayWithSeconds(1) {
//Do something
}
1)添加这个方法作为UIViewController Extension的一部分。
extension UIViewController{
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), block)
}
}
在VC上调用这个方法:
self.runAfterDelay(5.0, block: {
//Add code to this block
print("run After Delay Success")
})
2)
performSelector("yourMethod Name", withObject: nil, afterDelay: 1)
3)
override func viewWillAppear(animated: Bool) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue(), { () -> () in
//Code Here
})
/ /紧凑的形式
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue()) {
//Code here
}
}
在Swift 5中,在下面使用:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure)
// time gap, specify unit is second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
Singleton.shared().printDate()
}
// default time gap is second, you can reduce it
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
// just do it!
}
斯威夫特 3+
这在Swift 3+中是超级简单和优雅的:
DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
// ...
}
年长的回答:
为了扩展Cezary的答案,它将在1纳秒后执行,我必须执行以下操作以在4秒半后执行。
let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), block)
编辑:我发现我原来的代码有一点错误。如果不将NSEC_PER_SEC转换为Double类型,隐式类型将导致编译错误。
如果有人能提出一个更优的解决方案,我很乐意听听。