计时器不会按照您的想法“运行”。没有“倒计时”。计时器只是将标记添加到运行循环以在特定时间发送特定消息。每次运行循环时,它都会检查是否有任何计时器已过期(如果“现在”晚于它们的触发日期)。drawRect:
如果是这样,它会以与调用或处理触摸事件等其他事情相同的方式发送请求的消息。它或多或少是一个巨大的while (true)
循环,其中循环中的一件事是“触发过期计时器”。
那么这一切意味着什么呢?这意味着计时器只会在给定的运行循环被“泵送”(处理)时触发。通常这是主运行循环,它仅在您的应用程序处于活动状态时才被处理。如果您变得不活动(通常当用户导航到另一个应用程序时),那么 runloop 将不会处理。在您不活动时到期的所有计时器将在您回来时触发(这就是为什么您通常希望在进入后台之前使计时器无效)。(非主运行循环稍微复杂一些,但非常少见。虽然它们仍然不会在后台无限期运行,但在更多情况下它们无法运行。)
另一方面,如果你被终止了(当你在后台时可能会在没有通知的情况下发生),那么你的 runloops 就全部消失了。当您重新启动时,您的计时器将不会被实例化。如果你愿意,那是你的工作。所以你不能依赖你的计时器来触发。
因为您已包含repeats:YES
,计时器将自动为您重新安排。同样,这并不意味着它“倒计时”或“仍在运行”或类似的东西。这只是意味着当它触发时,它会自动安排另一个计时器事件。因此,如果用户只是在“确定”按钮上停留足够长的时间,计时器将再次触发(在 iOS 中;在 Mac 上情况可能会有所不同,“模式”在那里更重要)。
请注意,没有理由同时调用scheduledTimerWithTimeInterval:...
该addTimer:...
方法的“已调度”部分意味着计时器已添加到运行循环中。