dispatch_after - Swift中的GCD?

本文翻译自:dispatch_after - GCD in Swift?

I've gone through the iBook from Apple, and couldn't find any definition of it: 我从Apple那里浏览了iBook ,找不到任何定义:

Can someone explain the structure of dispatch_after ? 有人可以解释dispatch_after的结构吗?

dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)

#1楼

参考:https://stackoom.com/question/1cqTw/dispatch-after-Swift中的GCD


#2楼

A clearer idea of the structure: 更清楚的结构:

dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)

dispatch_time_t is a UInt64 . dispatch_time_t是一个UInt64 The dispatch_queue_t is actually type aliased to an NSObject , but you should just use your familiar GCD methods to get queues. dispatch_queue_t实际上是NSObject别名,但您应该使用熟悉的GCD方法来获取队列。 The block is a Swift closure. 该块是一个Swift闭包。 Specifically, dispatch_block_t is defined as () -> Void , which is equivalent to () -> () . 具体来说, dispatch_block_t定义为() -> Void ,相当于() -> ()

Example usage: 用法示例:

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    print("test")
}

EDIT: 编辑:

I recommend using @matt's really nice delay function . 我建议使用@ matt的非常好的delay功能

EDIT 2: 编辑2:

In Swift 3, there will be new wrappers for GCD. 在Swift 3中,将有新的GCD包装器。 See here: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md 请参阅: https//github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

The original example would be written as follows in Swift 3: 原始示例将在Swift 3中编写如下:

let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    print("test")
}

Note that you can write the deadlineTime declaration as DispatchTime.now() + 1.0 and get the same result because the + operator is overridden as follows (similarly for - ): 请注意,您可以将deadlineTime声明写为DispatchTime.now() + 1.0并获得相同的结果,因为+运算符被覆盖如下(类似于- ):

  • func +(time: DispatchTime, seconds: Double) -> DispatchTime
  • func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime

This means that if you don't use the DispatchTimeInterval enum and just write a number, it is assumed that you are using seconds. 这意味着如果您不使用DispatchTimeInterval enum并只写一个数字,则假定您使用秒。


#3楼

Swift 3+ Swift 3+

This is super-easy and elegant in Swift 3+: 这在Swift 3+中非常简单和优雅:

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    // ...
}

Older Answer: 旧答案:

To expand on Cezary's answer, which will execute after 1 nanosecond, I had to do the following to execute after 4 and a half seconds. 为了扩展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)

Edit: I discovered that my original code was slightly wrong. 编辑:我发现我的原始代码有点错误。 Implicit typing causes a compile error if you don't cast NSEC_PER_SEC to a Double. 如果不将NSEC_PER_SEC转换为Double,则隐式类型会导致编译错误。

If anyone can suggest a more optimal solution I'd be keen to hear it. 如果有人能提出更优化的解决方案,我会热衷于听到它。


#4楼

I use dispatch_after so often that I wrote a top-level utility function to make the syntax simpler: 我经常使用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)
}

And now you can talk like this: 现在你可以这样说:

delay(0.4) {
    // do stuff
}

Wow, a language where you can improve the language. 哇,一种你可以改善语言的语言。 What could be better? 还有什么比这更好的?


Update for Swift 3, Xcode 8 Seed 6 更新Swift 3,Xcode 8 Seed 6

Seems almost not worth bothering with, now that they've improved the calling syntax: 似乎几乎不值得打扰,现在他们已经改进了调用语法:

func delay(_ delay:Double, closure:@escaping ()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

#5楼

matt's syntax is very nice and if you need to invalidate the block, you may want to use this : matt的语法非常好,如果你需要使块无效,你可能想要使用它:

typealias dispatch_cancelable_closure = (cancel : Bool) -> Void

func delay(time:NSTimeInterval, closure:()->Void) ->  dispatch_cancelable_closure? {

    func dispatch_later(clsr:()->Void) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(time * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), clsr)
    }

    var closure:dispatch_block_t? = closure
    var cancelableClosure:dispatch_cancelable_closure?

    let delayedClosure:dispatch_cancelable_closure = { cancel in
        if closure != nil {
            if (cancel == false) {
                dispatch_async(dispatch_get_main_queue(), closure!);
            }
        }
        closure = nil
        cancelableClosure = nil
    }

    cancelableClosure = delayedClosure

    dispatch_later {
        if let delayedClosure = cancelableClosure {
            delayedClosure(cancel: false)
        }
    }

    return cancelableClosure;
}

func cancel_delay(closure:dispatch_cancelable_closure?) {

    if closure != nil {
        closure!(cancel: true)
    }
}

Use as follow 使用方法如下

let retVal = delay(2.0) {
    println("Later")
}
delay(1.0) {
    cancel_delay(retVal)
}

credits 学分

Link above seems to be down. 上面的链接似乎有所下降。 Original Objc code from Github 来自Github的原始Objc代码


#6楼

Another way is to extend Double like this: 另一种方法是像这样扩展Double:

extension Double {
   var dispatchTime: dispatch_time_t {
       get {
           return dispatch_time(DISPATCH_TIME_NOW,Int64(self * Double(NSEC_PER_SEC)))
       }
   }
}

Then you can use it like this: 然后你可以像这样使用它:

dispatch_after(Double(2.0).dispatchTime, dispatch_get_main_queue(), { () -> Void in
            self.dismissViewControllerAnimated(true, completion: nil)
    })

I like matt's delay function but just out of preference I'd rather limit passing closures around. 我喜欢亚光的延迟功能,但仅仅是出于偏好,我宁愿限制传递闭合。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值