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. 我喜欢亚光的延迟功能,但仅仅是出于偏好,我宁愿限制传递闭合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值