当前位置: 首页 > 知识库问答 >
问题:

如何在Swift3、4和5中编写dispatch_after GCD?

林修真
2023-03-14

在Swift 2中,我能够使用dispatch_after延迟使用中央调度的操作:

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

但自Swift3以来,这似乎不再编译了。用现代Swift写这篇文章的首选方式是什么?

共有3个答案

柯栋
2023-03-14

如果只希望延迟函数

Swift 4和5

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}

您可以这样使用它:

delay(interval: 1) { 
    print("Hi!")
}
魏襦宗
2023-03-14

雨燕4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

也可以使用.seconds(Int).microseconds(Int).nanseconds(Int)

荆煌
2023-03-14

语法很简单:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

注意,上面将seconds添加为double的语法似乎是一个混乱的来源(特别是因为我们已经习惯了添加nsec)。“add seconds asdouble”语法起作用,因为deadly是一个dispatchtime并且在幕后,有一个+运算符将使用double并向dispatchtime添加那么多秒:

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

但是,如果您确实想向DispatchTime添加毫秒、微秒或nsec的整数,您也可以向DispatchTime添加DispatchTimeInterval。这意味着您可以:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

由于DispatchTime类中的+运算符有这个单独的重载方法,所以这些都可以无缝地工作。

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

有人询问如何取消已调度的任务。为此,请使用DispatchWorkItem。例如,这将启动一个将在五秒内触发的任务,或者如果视图控制器被解除并释放,则其deinit将取消该任务:

class ViewController: UIViewController {

    private var item: DispatchWorkItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        item = DispatchWorkItem { [weak self] in
            self?.doSomething()
            self?.item = nil
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
    }

    deinit {
        item?.cancel()
    }

    func doSomething() { ... }

}

请注意在DispatchWorkItem中使用了[weak self]捕获列表。这对于避免强参考周期至关重要。还要注意,这并不是抢先取消,而是在任务尚未启动时停止它。但是,如果在遇到cancel()调用时它已经启动,则块将完成其执行(除非您手动检查块内的iscancelled)。

 类似资料:
  • 问题内容: 在Swift 2中,我能够使用大型中央调度来延迟动作: 但是,自Swift 3起,似乎不再可以编译了。在现代Swift中编写此代码的首选方法是什么? 问题答案: 语法很简单: 请注意,上述添加为a的语法似乎是造成混乱的根源(特别是因为我们习惯于添加nsec)。之所以可以使用“ add seconds as ”语法,是因为a 和在幕后,有一个运算符将占用a 并将其增加很多秒: 但是,如果

  • 问题内容: 已在Swift3中弃用。任何人都可以提供一些示例来说明尝试打开URL时替换的工作方式吗? 问题答案: 所有你需要的是:

  • 了解如何在“代码”视图中工作并充分利用 Dreamweaver 的编码功能。 可通过多种方式在 Dreamweaver 中处理代码。 您可以使用“新建文档”对话框打开新的代码文件,然后开始键入您的代码。在 Dreamweaver 中创建新的代码文件 键入时,会显示代码提示以帮助您选择代码和避免打字错误。如果需要,可使用 Dreamweaver 的有用的快捷文档获取 CSS 的相关帮助。 还可以使用

  • 我在mySql中有一个查询,我想在我的控制器中编写。 原因:java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:应为CLOSE,在org.hibernate.internal.exceptionConverterImpl.convert(exceptionConverterIm

  • 一篇GitBlog就是一个markdown文件,GitBlog使用解析markdown文件为html展示在网页上。所有的博客markdown文件必须放在posts文件夹里。后缀名只可以是xx.md或者xx.markdown。 注意: 2.2版本开始,所有markdown文件和图片统一放到blog文件夹中。查看gitblog目录结构说明。 发表一篇新博客 在posts里新建文件helloworld.

  • 有了ORM,我们就可以把Web App需要的3个表用Model表示出来: import time, uuid from transwarp.db import next_id from transwarp.orm import Model, StringField, BooleanField, FloatField, TextField class User(Model): __tab