在后台线程中调用NSTimer时无法使NSTimer无效

时间:2016-05-19 17:55:22

标签: ios objective-c multithreading grand-central-dispatch

我使用下面的代码去除选择器saveCurrentDocument的执行。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    if (debounceTimer != NULL) {
        [debounceTimer invalidate];
        debounceTimer = NULL;
    }

    debounceTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self  selector:@selector(saveCurrentDocument) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:debounceTimer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
});

目前,我注意到dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)每次用户在应用中键入字母时都会创建另一个线程,所以我尝试将其更改为:

if (debounceQueue == nil) {
    debounceQueue = dispatch_queue_create("com.testing.SaveQueue", NULL);
}

dispatch_async(debounceQueue, ^{
    if (debounceTimer != NULL) {
        [debounceTimer invalidate];
        debounceTimer = NULL;
    }

    debounceTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self  selector:@selector(saveCurrentDocument) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:debounceTimer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
});

但是现在[debounceTimer invalidate]不再起作用,并且每次调用saveCurrentDocument。

任何人都可以向我解释为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

看起来您正在将计时器添加到runloop两次。您应该删除addTimer并在实例化debounceTimer后运行行,或者您可以使用timerWithTimeInterval ...而不是scheduledTimerWithTimeInterval ...