You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

关键说明

  1. RunLoop保持活跃:Playground的needsIndefiniteExecution属性设置为true后,会维持RunLoop运行,Timer才能按时触发回调。
  2. 避免循环引用:原Selector方式的Timer会强引用target(即Test对象),而Test对象又持有Timer,形成循环引用导致对象无法释放。Block-based Timer配合[weak self]可以打破这个循环。
  3. 可选类型Timer:将timer声明为可选类型,避免初始化空的无效Timer,更符合实际逻辑。

内容的提问来源于stack exchange,提问作者marc0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:12:52