我翻遍了苹果的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?#>)
当前回答
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
}
}
其他回答
另一种方法是像这样扩展Double:
extension Double {
var dispatchTime: dispatch_time_t {
get {
return dispatch_time(DISPATCH_TIME_NOW,Int64(self * Double(NSEC_PER_SEC)))
}
}
}
然后你可以这样使用它:
dispatch_after(Double(2.0).dispatchTime, dispatch_get_main_queue(), { () -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
})
我喜欢matt的延迟函数,但只是出于偏好,我宁愿限制传递闭包。
另一个帮手来延迟你的代码,这是100%的Swift使用,并可选地允许选择一个不同的线程来运行你的延迟代码:
public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
let dispatchTime = DispatchTime.now() + seconds
dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}
public enum DispatchLevel {
case main, userInteractive, userInitiated, utility, background
var dispatchQueue: DispatchQueue {
switch self {
case .main: return DispatchQueue.main
case .userInteractive: return DispatchQueue.global(qos: .userInteractive)
case .userInitiated: return DispatchQueue.global(qos: .userInitiated)
case .utility: return DispatchQueue.global(qos: .utility)
case .background: return DispatchQueue.global(qos: .background)
}
}
}
现在你只需在主线程上延迟你的代码,就像这样:
delay(bySeconds: 1.5) {
// delayed code
}
如果你想延迟你的代码到不同的线程:
delay(bySeconds: 1.5, dispatchLevel: .background) {
// delayed code that will run on background thread
}
如果你喜欢一个框架,也有一些更方便的功能,然后签出handysswift。你可以通过Carthage将它添加到你的项目中,然后像上面的例子一样使用它,例如:
import HandySwift
delay(bySeconds: 1.5) {
// delayed code
}
我经常使用dispatch_after,所以我写了一个顶级实用函数来简化语法:
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
现在你可以这样说:
delay(0.4) {
// do stuff
}
哇,一种你可以改进的语言。还有什么比这更好的呢?
更新Swift 3, Xcode 8种子6
看起来几乎不值得费心,现在他们已经改进了调用语法:
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
使用这段代码在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 4有一个很短的方法来做到这一点:
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
// Your stuff here
print("hello")
}