如何在后台线程中运行NSTimer

时间:2017-01-05 11:12:36

标签: ios nstimer

我想使用NSTimer运行BackGround thread,因为我已经编写了以下代码,但我的NSTimer方法无法调用!

请一位有人帮助我

- (void)viewDidLoad {
       [super viewDidLoad];
       // Do any additional setup after loading the view.
        NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
        [operationQueue addOperationWithBlock:^{
        // Perform long-running tasks without blocking main thread

        [NSTimer scheduledTimerWithTimeInterval:2
                                                 target:self
                                               selector:@selector(targetMethod)
                                               userInfo:nil
                                                repeats:YES];
          }];
}

-(void)targetMethod{
         NSLog(@"Timer Called");
}

3 个答案:

答案 0 :(得分:1)

克里希,你似乎在这里走错了路。

首先,您应该通过调用scheduledTimerWithTimeInterval在主线程上创建计时器。将调用scheduledTimerWithTimerInterval调用到operationQueue是没有意义的。定时器从它们的线程的runloop中调用。尝试使用不同的operationQueue调度它们会让你遇到麻烦。

如果您希望在后台执行计时器的实际操作,请在计时器回调方法中使用dispatch_async(...)在后台运行代码。

除非您有正当理由不这样做,否则请在主线程上安排计时器。

您的回调方法应该有一个计时器参数。这样,您的回调方法可以操作计时器,例如通过使其无效。 scheduledTimer ...也返回计时器。通常,您将存储该计时器对象,以便在视图消失时使其无效。如果不这样做,每次调用viewDidLoad时都会得到一个新的NSTimer。也就是说,当您的应用程序运行时,您将有越来越多的计时器回调。

学习GCD(大中央调度)。它比操作队列简单得多。除非有充分的理由,否则不应使用操作队列。

当你问“我们如何停止后台线程”时 - 你没有。您将代码分派给它,代码运行,只要有代码被调度,它就会运行。如果没有代码调度后台,它将停止运行,直到您再次发送代码。这就是它应该如何工作。

如果你的意思是“如何停止计时器” - 那就是无效的。

PS。如果您从后台线程(您不想要,请相信我)安排计时器,可以在此处找到正确的答案:iOS5 ARC is it safe to schedule NSTimers from background selectors?

答案 1 :(得分:0)

您可以为BackGround线程使用GCD调度队列:=

 dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
                   {
                       NSTimer *timer = [NSTimer timerWithTimeInterval:0.5
                                                                target:self
                                                              selector:@selector(timerFired)
                                                              userInfo:nil repeats:YES];
                       [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
                       dispatch_async(dispatch_get_main_queue(), ^(void)
                                      {
                                      });
                   });

答案 2 :(得分:0)

NSTimer实际上并未在线程上运行。将计时器安排到主线程(实际上是它的NSRunLoop)仍然允许它在计时器触发之前处理事件并执行其他操作。

当计时器触发时,主线程NSRunLoop将调用目标+选择器,然后继续等待下一个事件。

我建议你用以下代码替换你的代码:

- (void)viewDidLoad {
       [super viewDidLoad];
       // Do any additional setup after loading the view.
       [NSTimer scheduledTimerWithTimeInterval:2
                                        target:self
                                      selector:@selector(targetMethod)
                                      userInfo:nil
                                       repeats:YES];
}

-(void)targetMethod{
         NSLog(@"Timer Called");
}

注意:如果targetMethod需要执行昂贵的操作,建议将它们安排到后台线程。