工人线程iOS

时间:2012-01-06 14:23:10

标签: iphone objective-c ios multithreading

我想在iPhone上创建一个后台线程,每10毫秒执行一些代码。 但在我迷失在并发编程指南和苹果再次的线程编程指南之前,我想问一下这里是否有人可以帮助我。 我想做什么:

  • 创建后台工作线程
  • 每10毫秒触发一次方法的执行。 (可能在该线程中使用NSTimer?)
  • 尽量减少主应用程序线程的负载

在我的理解中,继承NSThread并在该子类中编写我自己的main方法应该可以解决问题。这样我就不会使用NSTimer作为更新间隔,但是类似于:

[NSThread sleepForTimeInterval: 0.01];

主线程和工作线程之间的排队机制也没有任何意义,因为工作线程应该反复执行相同的操作 - 直到停止。

问题是:如何配置线程使用计时器?我看不出如何将NSTimer附加到该工作线程Run Loop?

4 个答案:

答案 0 :(得分:11)

使用您概述的方法可以做到这一点,但您是否看过使用Grand Central Dispatch?它可以使一些更容易:

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{
    while ([self shouldKeepProcessingInBackground]) {
        [self doBackgroundWork];
        usleep(1e4);
    }
})

您还可以使用计时器调度源定期执行工作:

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, backgroundQueue);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, 0), 0.01*NSEC_PER_SEC, 0*NSEC_PER_SEC);
dispatch_source_set_event_handler(timerSource, ^{
    [self doBackgroundWork];
});
dispatch_resume(timerSource);

答案 1 :(得分:2)

NSRunLoop是缺失的链接。

您必须设置线程的运行循环才能重复,或者您可以从线程的条目中控制它。线程主持定时器(如果定时器仍处于活动状态,定时器将以运行循环死亡)。

NSRunLoop是一个非常小的类 - 检查它和相关的样本。

答案 2 :(得分:1)

您可以轻松使用GCD(大中央调度)。首先创建一个将在后台调用的选择器。从这里打电话给你想要的任何方法。

- (void)backgroundSelector
{
    // do whatever you want to do
    [self performSelector:@selector(backgroundSelector) withObject:nil afterDelay:0.01];
}

之后,就像这样第一次点燃这个方法

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    [self backgroundSelector];
});

请告诉我这是否适合您。

答案 3 :(得分:0)

如果你用NSThread做的话,它非常简单和干净。无需将其子类化。

- (void)backgroundStuff {
    while (!self.cancelThread) {
        // do your work
        [NSThread sleepForTimeInterval:0.01];
    }
}

只是一个普通的功能。 cancelThread是您声明的成员变量。从

开始
[NSThread detachNewThreadSelector:@selector(backgroundStuff) toTarget:self withObject:nil];

你可以随时使用self.cancelThread = true;

来取消线程