Swift开发:创建对象时启动Timer失败,如何解决?
解决Swift Playground中创建对象时Timer无法启动的问题
你的代码在常规iOS项目中可以正常运行,但在Playground里Timer无法启动的核心原因是:Playground默认执行完初始化代码后就会终止运行,不会保持RunLoop活跃,而Timer依赖RunLoop来触发事件。另外原代码还存在循环引用的潜在问题,以下是完整的修复方案:
步骤1:配置Playground保持运行
在Playground最开头添加以下代码,让Playground持续运行而不是立即结束:
import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true
步骤2:修改Test类的Timer实现
改用Block-based Timer并处理循环引用问题,同时优化Timer的初始化逻辑:
import Foundation class Test { var counter = 60 var timer: Timer? init() { // 使用Block-based Timer,配合weak self避免循环引用 timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in guard let self = self else { timer.invalidate() return } if self.counter > 0 { self.counter -= 1 print(self.counter) } else { self.counter = 60 } } } // 销毁对象时及时释放Timer deinit { timer?.invalidate() print("Test对象已释放") } }
步骤3:测试代码
创建Test对象后,Timer就会自动启动并执行计数逻辑:
var newTest = Test() // 如需手动停止Timer,可调用:newTest.timer?.invalidate()
关键说明
- RunLoop保持活跃:Playground的
needsIndefiniteExecution属性设置为true后,会维持RunLoop运行,Timer才能按时触发回调。 - 避免循环引用:原Selector方式的Timer会强引用target(即Test对象),而Test对象又持有Timer,形成循环引用导致对象无法释放。Block-based Timer配合
[weak self]可以打破这个循环。 - 可选类型Timer:将timer声明为可选类型,避免初始化空的无效Timer,更符合实际逻辑。
内容的提问来源于stack exchange,提问作者marc0
相关产品推荐
相关产品推荐

