NSTimer的奇怪行为

时间:2014-04-27 12:11:07

标签: ios objective-c nstimer nsoperationqueue core-motion

我似乎无法解决这个问题。这是我的设置:

我有一个名为requestDataWithCompletion:(someBlock)block的函数。我在初始化类时调用它。该功能请求某些运动数据。我想定期这样做,因此,第一次调用这个函数时,我指定了一些完成代码,它设置了一个定期重新调用该函数的定时器。计时器通过另一个函数requestDataWithoutCompletion调用它,它只是调用requestDataWithCompletion但是空块(所以我不会继续创建计时器);

- (void) requestDataWithCompletion:(someBlock)block {
// BREAK POINT 1
        [self.motionManager queryActivityStartingFromDate:start toDate:[NSDate date] toQueue:self.queue withHandler:^(NSArray *activities, NSError *error) { 
// BREAK POINT 2
            // do some processing; 
            block();
        }];
    }

该块只是在主队列上创建一个计时器,它定期调用此功能,但没有完成(因为我不想继续创建更多的计时器)。

block = ^{
      dispatch_async(dispatch_get_main_queue(), ^{
            self.timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval 
target:self selector:@selector(requestDataWithoutCompletion) userInfo:nil repeats:YES];
            });
    }

- (void) requestDataWithoutCompletion {
[self requestDataWithCompletion^{;}];
}

令人惊奇的是,尽管有这个设置,我的应用程序正在计时器后创建计时器!我不明白为什么。

我在requestDataWithCompletion方法中放置了断点。一个在提交给NSOperationQueue的块之外以获取活动数据(BREAKPOINT 1),一个在提交给NSOperationQueue.的块内(BREAKPOINT 2)。基本上它表明每次定时器调用该方法时,BREAKPOINT 1都有一个空的完成块(应该是这样),但奇怪的是BREAKPOINT 2在我初始化类时第一次调用函数时有我提交的完成块。因此,每次定时器调用该函数时,它都会继续创建一个新的定时器。随着时间的推移,这意味着大量的计时器,然后应用程序崩溃!

我觉得这与NSOperationQueue有关,但我真的不知道它可能是什么。

1 个答案:

答案 0 :(得分:0)

在初始化过程中(或者当您第一次想要获取数据然后继续获取数据时):

self.timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(requestDataWithoutCompletion) userInfo:nil repeats:YES];
[self.timer fire]; //get the activity data immediately. 

- (void) requestDataWithoutCompletion {
    [self requestDataWithCompletion:^{}];
}

使用原始requestDataWithCompletion:方法。 (虽然如果你不在其他地方使用它,你可以摆脱requestDataWithCompletion:并将其直接放在requestDataWithoutCompletion中。