dispatch_after - Swift中的GCD?

 手机用户2502855763 发布于 2023-01-11 18:02

我从Apple那里浏览了iBook,找不到任何定义:

有人可以解释结构dispatch_after吗?

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

matt.. 1086

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 Seed 6

似乎几乎不值得打扰,现在他们已经改进了调用语法:

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

不要质疑你答案的正确性 - 但不是*"我经常使用dispatch_after"*代码气味最好是**而不是**提供便利功能? (8认同)

"一种可以改善语言的语言".我不明白定义一个全局函数如何改进语言,或者为什么这在C语言中是不可行的.也许如果你重载一个运算符;)`1.0 ~~ {code ...}` (7认同)

@ agf119105如果闭包中只有一行代码,则添加另一行代码(例如`return`). (4认同)

我只需要延迟计算的快捷方式,最后得到:`func delayInSec(delay:Double) - > dispatch_time_t {return dispatch_time(DISPATCH_TIME_NOW,Int64(delay*Double(NSEC_PER_SEC)))}` (2认同)

@GastonM不相关.传递函数_of本身_没有内存管理问题. (2认同)


Cezary Wojci.. 730

更清楚的结构:

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

dispatch_time_t是一个UInt64.在dispatch_queue_t被实际键入别名的NSObject,但你应该只使用自己熟悉的GCD方法来获取队列.该块是一个Swift闭包.具体而言,dispatch_block_t被定义为() -> Void,相当于() -> ().

用法示例:

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

编辑:

我推荐使用@ matt的非常好的delay功能.

编辑2:

在Swift 3中,将有新的GCD包装器.请参阅:https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

原始示例将在Swift 3中编写如下:

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

请注意,您可以将deadlineTime声明编写为DispatchTime.now() + 1.0并获得相同的结果,因为+运算符被覆盖如下(类似于-):

func +(time: DispatchTime, seconds: Double) -> DispatchTime

func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime

这意味着如果您不使用DispatchTimeInterval enum并只写一个数字,则假定您使用秒.

8 个回答
  • 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)
        }
    }
    

    使用方法如下

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

    学分

    上面的链接似乎有所下降.来自Github的原始Objc代码

    2023-01-11 18:03 回答
  • 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 Seed 6

    似乎几乎不值得打扰,现在他们已经改进了调用语法:

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

    2023-01-11 18:03 回答
  • Swift 3.0和Swift 4.0中最简单的解决方案

    func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
        DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
            completion()
        }
    }
    

    用法

    delayWithSeconds(1) {
       //Do something
    }
    

    2023-01-11 18:03 回答
  • Apple有一个针对Objective-Cdispatch_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#>
    }
    

    2023-01-11 18:03 回答
  • 为了扩展Cezary的答案,它将在1纳秒后执行,我必须在4秒半后执行以下操作.

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

    编辑:我发现我的原始代码有些错误.如果不将NSEC_PER_SEC转换为Double,则隐式类型会导致编译错误.

    如果有人能提出更优化的解决方案,我会热衷于听到它.

    == Swift 3的更新==

    这在Swift 3中非常简单和优雅:

    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)
    

    2023-01-11 18:03 回答
  • 更清楚的结构:

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

    dispatch_time_t是一个UInt64.在dispatch_queue_t被实际键入别名的NSObject,但你应该只使用自己熟悉的GCD方法来获取队列.该块是一个Swift闭包.具体而言,dispatch_block_t被定义为() -> Void,相当于() -> ().

    用法示例:

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

    编辑:

    我推荐使用@ matt的非常好的delay功能.

    编辑2:

    在Swift 3中,将有新的GCD包装器.请参阅:https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

    原始示例将在Swift 3中编写如下:

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

    请注意,您可以将deadlineTime声明编写为DispatchTime.now() + 1.0并获得相同的结果,因为+运算符被覆盖如下(类似于-):

    func +(time: DispatchTime, seconds: Double) -> DispatchTime

    func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime

    这意味着如果您不使用DispatchTimeInterval enum并只写一个数字,则假定您使用秒.

    2023-01-11 18:04 回答
  • 另一种方法是像这样扩展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)
        })
    

    我喜欢亚光的延迟功能,但仅仅是出于偏好,我宁愿限制传递闭合.

    2023-01-11 18:04 回答
  • 在Swift 3.0中

    派遣队列

      DispatchQueue(label: "test").async {
            //long running Background Task
            for obj in 0...1000 {
                print("async \(obj)")
            }
    
            // UI update in main queue
            DispatchQueue.main.async(execute: { 
                print("UI update on main queue")
            })
    
        }
    
        DispatchQueue(label: "m").sync {
            //long running Background Task
            for obj in 0...1000 {
                print("sync \(obj)")
            }
    
            // UI update in main queue
            DispatchQueue.main.sync(execute: {
                print("UI update on main queue")
            })
        }
    

    5秒后发货

        DispatchQueue.main.after(when: DispatchTime.now() + 5) {
            print("Dispatch after 5 sec")
        }
    

    2023-01-11 18:04 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有