无法让我在 Swift 中的计时器在 Playground 中触发

Posted

技术标签:

【中文标题】无法让我在 Swift 中的计时器在 Playground 中触发【英文标题】:Can't get my Timer in Swift to fire in Playground 【发布时间】:2015-10-27 22:14:44 【问题描述】:

我正在尝试使用 Swift 和 GCD 制作一个不错的计时器。我在 Matt Neuburg 的书中找到了很多博客,甚至一个条目。我用后者在操场上组装了我自己的变体:

import Foundation
struct Timer 
    private var queue = dispatch_queue_create("timer", nil)
    private var source: dispatch_source_t
    var tick:()->() =  
        didSet 
            self.update()
        
    
    var rate:Double = 1.0 
        didSet 
            self.update()
        
    

    init() 
        self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue)
        self.update()
    

    func cancel() 
        dispatch_source_cancel(self.source)
    

    func update() 
        dispatch_source_set_timer(self.source, DISPATCH_TIME_NOW, UInt64(Double(NSEC_PER_SEC) / self.rate), 0)
        dispatch_source_set_event_handler(self.source, self.tick)
    

    func resume() 
        dispatch_resume(self.source)
    


var timer = Timer()
timer.tick = 
    let now = NSDate()
    print("\(now)")

timer.cancel()
timer.resume()

我没有编译错误。但是操场底部的控制台什么也没显示。如果我添加

timer.tick()

它输出当前日期的结果,显然是执行一次tick函数。我非常密切地遵循了马特在他的书中的例子(出于教育目的进行了一些小改动)。所以我不知道是否

A)它很好,当我将它移到真实代码时会正常工作,它只是没有显示在 Playground 输出中的任何明显位置 B) 有些东西没有丢失,也没有真正触发

【问题讨论】:

【参考方案1】:

一旦某个源被dispatch_source_cancel 取消,它将永远不会再次调用其事件处理程序。取消后无法使用dispatch_resume 重新启用源;您必须创建一个新源。

要使您的 Playground 正常工作,您必须删除对 timer.cancel() 的调用。

此外,在整个 Playground 脚本执行完毕后,Playground 进程默认退出。如果你想让它继续运行,你需要设置XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

所以让你的脚本的结尾看起来像这样:

var timer = Timer()
timer.tick = 
    let now = NSDate()
    print("\(now)")

timer.resume()
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

【讨论】:

以上是关于无法让我在 Swift 中的计时器在 Playground 中触发的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 计时器无法访问更新的实例属性

Tableview 中的 Swift Firebase Firestore 数据

如何将计时器中的数据传递给新的 ViewController (Swift 3)

如何在仍可以更改工作表中的值的情况下在vba excel中执行Do Event计时器?

Swift 5 - 无法解释的 DateFormatter 崩溃

Swift:点击手势无法识别