performSelectorInBackgroundThread和NSTimer

pgb*_*pgb 2 iphone multithreading objective-c

对于我正在开发的游戏,我从其中一个触摸处理程序中调用了一种昂贵的方法.为了使它更快,我决定使用performSelectorInBackgroundThread,所以而不是:

[gameModel processPendingNotifications];
Run Code Online (Sandbox Code Playgroud)

我切换到:

[gameModel  performSelectorInBackground:@selector(processPendingNotifications) withObject:nil];
Run Code Online (Sandbox Code Playgroud)

我遇到的第一个问题是processPendingNotifications没有NSRunLoop,所以我添加了它,就像这样:

- (void)processPendingNotifications {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [pendingNotificationsQueue makeObjectsPerformSelector:@selector(main)];
    [pendingNotificationsQueue removeAllObjects];
    [pool drain];
}
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.我的问题是从这个后台线程调用的一些方法创建了新NSTimer实例.这些情况最终没有解雇.我认为这是因为我所拥有的辅助线程没有(或正在结束它)NSRunLoop.我正在使用以下方式启动新计时器:

[NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(timerFired) userInfo:nil repeats:NO];
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 我是否在正确的道路上怀疑问题与NSRunLoop?有关?
  2. 有没有办法NSTimer从后台线程启动并将其附加到主线程NSRunLoop

Lou*_*arg 7

是的,您需要一个runloop来调度计时器事件

NSTimers隐式附加到它们所创建的线程的runloop上,因此如果你想将它附加到主线程的runloop,则使用performSelectorOnMainThread:withObject:waitUntilDone:在主线程上创建它.当然,该代码将在主线程上执行.

如果您的问题是"我可以在主线程的运行循环上运行一个直接在另一个线程上运行选择器的计时器吗?" 答案是否定的,但它在主线程上触发的选择器只能执行Next:onThread:withObject:waitUntilDone:.当然,这需要您尝试执行选择器的线程具有可操作的runloop.

如果你想要定时器触发在后台线程上运行的代码,那么你真的需要让后台线程的runloop运行,如果你这样做,那么你不需要使用主线程安排任何事情,因为你将有一个操作runloop.