【发布时间】:2011-05-27 23:17:55
【问题描述】:
我正在查看来自 iOS SDK (http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html) 的“Metronome”示例代码。我以 60 BPM 的速度运行节拍器,这意味着每秒一个滴答声。当我查看外接手表(PC 的手表)时,我发现节拍器运行速度太慢 - 它每分钟错过一个节拍,这就是 app。 15 毫秒的一致错误。相关的代码片段是:
- (void)startDriverTimer:(id)info {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Give the sound thread high priority to keep the timing steady.
[NSThread setThreadPriority:1.0];
BOOL continuePlaying = YES;
while (continuePlaying) { // Loop until cancelled.
// An autorelease pool to prevent the build-up of temporary objects.
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
[self playSound];
[self performSelectorOnMainThread:@selector(animateArmToOppositeExtreme) withObject:nil waitUntilDone:NO];
NSDate *curtainTime = [[NSDate alloc] initWithTimeIntervalSinceNow:self.duration];
NSDate *currentTime = [[NSDate alloc] init];
// Wake up periodically to see if we've been cancelled.
while (continuePlaying && ([currentTime compare:curtainTime] != NSOrderedDescending)) {
if ([soundPlayerThread isCancelled] == YES) {
continuePlaying = NO;
}
[NSThread sleepForTimeInterval:0.01];
[currentTime release];
currentTime = [[NSDate alloc] init];
}
[curtainTime release];
[currentTime release];
[loopPool drain];
}
[pool drain];
}
在哪里
self.duration
在 60 BPM 的情况下为 1.0 秒。我想知道这个错误来自哪里,以及如何制作更准确的计时器/间隔计数器。
编辑:当我将睡眠时间更改为较小的值时,问题也存在,例如 .001。
EDIT2(更新):当我使用CFAbsoluteTimeGetCurrent() 方法进行计时时,问题也存在。当我使用相同的方法测量按钮点击事件之间的时间时,时间似乎准确 - 我每秒点击一次(在观看手表时),测量的速率为 60 BPM(平均)。所以我想NSThread(?)一定有问题。另一件事是,在设备 (iPod) 上,问题似乎比在模拟器上更严重。
【问题讨论】:
标签: cocoa-touch ios time ios4