M1 MacOS上运行iOS应用程序的计时器和调试问题

M1 MacOS上运行iOS应用程序的计时器和调试问题,ios,macos,timer,apple-m1,Ios,Macos,Timer,Apple M1,我的iOS应用程序在主调度队列中运行一个可重复的计时器,定期更新UI屏幕状态。它在iPhone和iPad上正常运行。当它在M1 MacOS上运行时,计时器似乎没有按预期运行-调用计时器的速度比定义的时间间隔快得多 DispatchQueue.main.async { self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: {

我的iOS应用程序在主调度队列中运行一个可重复的计时器,定期更新UI屏幕状态。它在iPhone和iPad上正常运行。当它在M1 MacOS上运行时,计时器似乎没有按预期运行-调用计时器的速度比定义的时间间隔快得多

DispatchQueue.main.async {
    self.timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true,
            block: { 
                     // runs code to update UI
            })
}
此外,是否有什么好方法可以调试运行在M1 MacOS上的iOS应用程序(如在XCode中设置调试断点),而不是在每次更改后从app Store重新安装/升级iOS应用程序


非常感谢您的建议。

我们没有您在问题中调用代码的更广泛背景。从理论上讲,可能存在一些在不同机器上表现不同的竞争条件。或者,在M1设备上进行测试时,测试程序存在细微差异

无论如何,有几种防御编程技术可以解决这类问题:

  • 我会确保
    定时器
    变量。
    RunLoop
    将为您保留对计时器的强引用,因此您无需保留自己对计时器的强引用:

    弱var定时器:定时器?
    
    这样,当计时器失效时,该参考将自动设置为
    nil

  • 创建计时器时,
    使前一个计时器(如果有)无效。如果您曾多次意外调用此例程,这将保护您:

    DispatchQueue.main.async{
    self.timer?.invalidate()//使前一个计时器失效(如果有)
    self.timer=timer.scheduledTimer(withTimeInterval:1,repeats:true){[weak self]timer in
    保护自己=保护自己{
    计时器?.invalidate()
    返回
    }
    //运行代码以更新UI
    }
    }
    
  • 请注意,除了
    在调度模式之前使无效之外,我还

    • 我在闭包中使用
      [weak self]
      模式,确保重复计时器不会无意中保留对当前对象的强引用

    • 我使用
      guard let self=self else…
      模式来
      使计时器失效
      返回
      ,如果相关对象被释放

    但关键的一点是,我们希望使用带有重复计时器的
    [弱自我]
    来防止强引用循环

  • 或者,如果对象在下一次激发时被释放,上面的代码将停止计时器,但我通常也会在对象被释放后立即显式停止计时器

    脱硝{
    计时器?.invalidate()
    }
    

  • 上述步骤的组合将确保每个对象只能有一个计时器,无论调用此例程的频率如何。这些步骤将有助于防止多个计时器同时运行。

    是,如果self.timer!=nil{print(“计时器已在运行”)}else{self.Timer=…}
    并查看您得到了什么