我翻遍了苹果的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?#>)
当前回答
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#>
}
其他回答
我经常使用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)
}
另一种方法是像这样扩展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
}
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#>
}
我总是喜欢使用扩展而不是自由函数。
斯威夫特4
public extension DispatchQueue {
private class func delay(delay: TimeInterval, closure: @escaping () -> Void) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class func performAction(after seconds: TimeInterval, callBack: @escaping (() -> Void) ) {
DispatchQueue.delay(delay: seconds) {
callBack()
}
}
}
按以下方法使用。
DispatchQueue.performAction(after: 0.3) {
// Code Here
}