如果某个 NSTimer 是使用 scheduledTimerWithTimeInterval 创建的,我如何找出它处于哪个 运行 循环?

How can I find out which run loop a certain NSTimer is on if it was created with scheduledTimerWithTimeInterval?

如果我用 scheduledTimerWithTimeInterval 做了一个 NSTimer,那么根据文档,它应该被添加到当前的 运行 循环中。我想知道如何检查 NSTimer 打开了哪个 运行 循环。

此外,如果计时器失效并创建了一个新计时器,我如何将新计时器添加到与第一个计时器相同的 运行 循环中在?

提前致谢。

当您使用该方法时,它被放置在当前线程上。如果你想在调用方法之前获得当前线程,调用`[NSRunLoop currentRunLoop']并跟踪它。或者你可以明确地将它放在一个线程上并跟踪它:

 NSTimer *timer = [NSTimer timerWithTimeInterval:0.5
                                       target:self
                                     selector:@selector(timerFired:)
                                     userInfo:nil repeats:YES];
[<Insert NSRunLoop> addTimer:forMode:] 

您可以在使前一个计时器无效并立即将新计时器添加到同一循环后立即使用它。

I'd like to know how to check which run loop an NSTimer is on.

当您安排原始计时器时,您可以保存对 [NSRunLoop currentRunLoop] 的引用,以便您知道它被添加到哪个 运行 循环中。您也可以在计时器的事件处理程序中使用 currentRunLoop

但是没有简单的 NSTimer method/property 可用于查询任意 NSTimer 已安排在哪个 运行 循环中。 NSRunLoop 对象也没有公开任何方法来允许应用程序开发人员查询在该特定 运行 循环上安排了哪些计时器。

Also, if a timer is invalidated and a new one is created, how can I add the new timer to the same run loop that the first timer was on?

一般来说,如果您想在 NSRunLoop 而不是当前的 NSRunLoop 上安排 NSTimer,而不是调用 scheduledTimerWithTimeInterval,您可以使用 [=19] 实例化计时器=],然后使用 运行 循环的 addTimer:mode: 方法将此计时器手动添加到特定的 NSRunLoop


所有这些都引出了一个问题,即为什么要在除主循环之外的任何 运行 循环上安排计时器。如果你想从后台线程使用 NSTimer,你必须在那个后台线程上创建你自己的 运行 循环(这有点低效,除非你有一个非常令人信服的理由)。

通常在使用 NSTimer 时,您只需将它安排在主 运行 循环中(例如,从主线程安排它),这样就不需要所有这些复杂的逻辑创建 运行 循环,跟踪哪个定时器被安排在哪个 运行 循环上,以及与在同一个 运行 循环上手动安排新定时器相关的逻辑。 运行 主循环通常足以优雅地处理多个计时器。

如果你真的需要 运行 在主线程以外的线程上的定时器,你可能要考虑使用 GCD 调度定时器,它可以在任何调度队列上调度,而不需要任何额外的运行 循环。 (但是,如果您想将更多计时器安排到与之前某个计时器相同的队列中,则必须跟踪添加了调度计时器的队列。)