【问题标题】:Running and managing NSTimer in different NSThread/NSRunLoop在不同的 NSThread/NSRunLoop 中运行和管理 NSTimer
【发布时间】:2010-06-17 18:47:49
【问题描述】:

我正在编写一个 Cocoa 应用程序,其 GUI 是在 Interface Builder 中设计的。我需要在不阻塞 UI 的情况下(定期)安排后台活动,因此我在单独的线程中运行它,如下所示:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [self performSelectorInBackground:@selector(schedule) withObject:nil];
}

- (void) schedule {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];

    timer = [[NSTimer scheduledTimerWithTimeInterval:FEED_UPDATE_INTERVAL
                                                  target:activityObj
                                        selector:@selector(run:)
                                        userInfo:nil
                                         repeats:YES]
         retain];

    [runLoop run];
    [pool release];
}

我保留了计时器,因此我可以轻松地使计时器失效并重新安排时间。

问题:我还必须触发 run: 方法以响应 GUI 事件,因此它是同步的(即“执行活动”按钮)。像这样:

[timer fire];

我也可以使用 performSelectorInBackground 来做到这一点,当然它不会阻塞 UI。但是这种同步触发在另一个运行循环中运行!所以我不能保证它们不会重叠。如何在同一个运行循环中将所有触发排队?

【问题讨论】:

    标签: objective-c cocoa multithreading nstimer nsrunloop


    【解决方案1】:
    [timer setFireDate:[NSDate distantPast]];
    

    我通过将下一个触发日期调整为 ASAP,将过去的日期传递给 setFireDate,从而获得了预期的效果。

    【讨论】:

      【解决方案2】:

      您可以使用经典的并发解决方案:信号量。在您的情况下,最简单的方法是使用 @synchronized 指令。用@synchronized 包围run: 方法的整个主体(或至少是敏感部分)。对于同步对象,我建议您使用特定的 ivar 或静态变量而不是 activityObj 的类,以避免死锁。

      -(void)run:(id)param {
          // do thread-safe things here
          @synchronized(syncObj) {
              // put your critical section here
          }
          // do more thread-safe things here
      }
      

      临界区的代码不会重叠。

      【讨论】:

        【解决方案3】:

        您应该在 mainThread 上安排 NSTimer(并触发计时器以执行选择器 --- 选择器可以在后台线程上执行,因此不会阻塞 UI),而不是通过 GCD 在后台线程上安排 NSTimer,因为 NSTimer将被添加到一个 NSRunLoop 中,并且每个 NSRunLoop 都与一个 NSTread 相关联。所以在使用 GCD 时,使用 dispatch_after 而不是 NSTimer 来延迟事情的发生。

        【讨论】:

          猜你喜欢
          • 2011-01-06
          • 2010-11-10
          • 1970-01-01
          • 2023-04-04
          • 2013-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多