转换到后台时 NSTimer 不可靠
NSTimer not reliable when transitioning to background
我正在使用 NSTimer 每 x 秒播放一次音频文件。音频文件与持续 运行 进程同步,因此 NSTimer 的间隔是最短的(据我所知):
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(updateTimerFired:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.updateTimer forMode:NSRunLoopCommonModes];
我的问题发生在转换到后台状态的过程中,例如当用户点击主页按钮时。似乎定时器发生了延迟,并且 "updateTimerFired:" 方法在转换期间没有被可靠地调用。这会导致音频文件播放不同步,尽管它们最终会在转换完成后同步备份。请注意,我的应用程序包含音频背景模式。
有没有比NSTimer更靠谱的工具保证转后台不卡顿?
最终将 NSTimer 替换为 dispatch_source_create
:
self.timerQueue = dispatch_queue_create("updateTimerQueue", nil);
self.updateTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.timerQueue);
dispatch_source_set_timer(self.updateTimer, DISPATCH_TIME_NOW, (1 * NSEC_PER_SEC) / 50, (1 * NSEC_PER_SEC) / 20);
dispatch_source_set_event_handler(self.updateTimer, ^{
[self updateTimerFired];
});
dispatch_resume(self.updateTimer);
这为计时器提供了一个专用队列来执行,并且不会被后台转换中断。
我正在使用 NSTimer 每 x 秒播放一次音频文件。音频文件与持续 运行 进程同步,因此 NSTimer 的间隔是最短的(据我所知):
self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(updateTimerFired:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.updateTimer forMode:NSRunLoopCommonModes];
我的问题发生在转换到后台状态的过程中,例如当用户点击主页按钮时。似乎定时器发生了延迟,并且 "updateTimerFired:" 方法在转换期间没有被可靠地调用。这会导致音频文件播放不同步,尽管它们最终会在转换完成后同步备份。请注意,我的应用程序包含音频背景模式。
有没有比NSTimer更靠谱的工具保证转后台不卡顿?
最终将 NSTimer 替换为 dispatch_source_create
:
self.timerQueue = dispatch_queue_create("updateTimerQueue", nil);
self.updateTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.timerQueue);
dispatch_source_set_timer(self.updateTimer, DISPATCH_TIME_NOW, (1 * NSEC_PER_SEC) / 50, (1 * NSEC_PER_SEC) / 20);
dispatch_source_set_event_handler(self.updateTimer, ^{
[self updateTimerFired];
});
dispatch_resume(self.updateTimer);
这为计时器提供了一个专用队列来执行,并且不会被后台转换中断。