无法让 Swift 中的计时器在 Playground 中触发
Can't get my Timer in Swift to fire in Playground
我正在尝试使用 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) 没有丢失的东西,它并没有真正开火
一旦源被 dispatch_source_cancel
取消,它将永远不会再次调用其事件处理程序。取消后无法使用 dispatch_resume
重新启用源;您必须创建一个新来源。
要使您的游乐场正常工作,您必须删除对 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 和 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) 没有丢失的东西,它并没有真正开火
一旦源被 dispatch_source_cancel
取消,它将永远不会再次调用其事件处理程序。取消后无法使用 dispatch_resume
重新启用源;您必须创建一个新来源。
要使您的游乐场正常工作,您必须删除对 timer.cancel()
的调用。
另外,整个playground脚本执行完毕后,playground进程默认退出。如果你想让它保持运行,你需要设置XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
.
所以让脚本的结尾看起来像这样:
var timer = Timer()
timer.tick = {
let now = NSDate()
print("\(now)")
}
timer.resume()
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true