当前位置: 首页 > 面试题库 >

为什么在块外而不是在块内设置时,`scheduledTimer`会正确启动?

廖诚
2023-03-14
问题内容

以下代码段在完成块外部调用时可以完美地工作,但是当我在完成块内部进行设置时,计时器永远不会触发。我不明白为什么会有区别:

self.timer = Timer.scheduledTimer(timeInterval: 1,
                                  target: self,
                                  selector: #selector(self.foo),
                                  userInfo: nil,
                                  repeats: true)

最初在块外部调用它时,我没有使用自引用,但在内部调用它时,它是必需的。但是,我再次在块外测试了完全相同的代码,它仍然起作用。

该块是一个完成处理程序,在请求HealthKit相关信息的许可后被调用。


问题答案:

问题在于所讨论的完成块可能未在主线程上运行,因此没有运行循环。但是计时器需要在运行循环中进行调度,而主线程只有一个,而大多数后台线程则没有(除非您自己添加一个)。

为了解决这个问题,在该完成处理程序中,将计时器的创建分派回主线程,并且应该可以正常工作:

DispatchQueue.main.async {
    self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}

或使用调度源计时器(可以为后台队列安排的计时器,并且不需要运行循环)。

var timer: DispatchSourceTimer!

private func startTimer() {
    let queue = DispatchQueue(label: "com.domain.app.timer")
    timer = DispatchSource.makeTimerSource(queue: queue)
    timer.setEventHandler { [weak self] in
        // do something
    }
    timer.schedule(deadline: .now(), repeating: 1.0)
    timer.resume()
}


 类似资料:
  • 我正在尝试构建一个私有模块,我知道它只会被另一个TypeScript项目使用。 据此,(https://github.com/Microsoft/TypeScript/issues/5225)我应该能够简单地导入我的其他项目,而不需要构建类型定义。 问题是,当我试图导入该库时,我缺少该库上任何依赖项的类型定义。 情况如下: 假设你有两个项目<代码>库和导入,这是一个纯类型脚本节点模块。 只是从导入

  • 我正在尝试制作两个程序。我希望一个打印我居住的城市的当前天气,我希望另一个从一个在线帐户获取数据并返回它。对于这些脚本,我导入了天气模块和请求模块。当我在shell中导入它们时,没有问题,但是当我运行脚本时,它说“ImportError:No module name you weather”。我做错了什么? 壳牌: 脚本: 这也适用于“天气”模块 谢谢你

  • 问题内容: 在下面的Java程序中,即使成员“ x”在try块之外定义,也可以在try块内部访问它。如果是“ y”,则在try块内定义。但是在try块之外无法访问它。为什么会这样呢? 输出为: 问题答案: 任何块都定义Java中的作用域。因此,在try块内声明的任何变量(例如)都只能在try块内访问。 在包含try块的外部块(即整个方法的块)中声明,因此可以在try块内部访问它。

  • 问题内容: 我的代码如下: 如果在获取之前设置标题,可以吗?我的标头会被发送,还是服务器会看到默认的用户代理(如果有)? 问题答案: 必须 先设置标头,然后才能产生任何影响- 如果连接已经打开,则将引发。 就头而言,如果已设置,则应将其发送。 请参阅URLConnection JavaDoc。

  • 我正在使用CentOS 6.3 64位计算机。我在catalina.sh export catalina_opts=“-dcom.sun.management.jmxremote=true-dcom.sun.management.jmxremote.port=7010-dcom.sun.management.jmxremote.ssl=false-dcom.sun.management.jmxre

  • 我需要解释一下,为什么执行了while()语句中的if()块。据说:while语句计算表达式,表达式必须返回布尔值。如果表达式的计算结果为true,则while语句将执行while块中的语句。请看一下这个代码: 一旦变量x超过5,不应该将其视为false吗?那么,如果执行块,该如何执行呢?基本上,它似乎为表达式5返回了真正的布尔值=5. 谢谢你的解释!