如何在准确的时间安排iOS方法调用

我希望iOS能够在将来的某个时间调用我的对象的方法。 调用该方法的时间可能比当前时间长达4小时。

我知道我可以使用NSTimer ,但我担心它对我的应用程序来说不够精确(即在30-50毫秒内):“计时器不是实时机制;只有在其中一个已经添加了计时器的运行循环模式正在运行,并且能够检查计时器的触发时间是否已经过去。“

我也看到过使用CADisplayLink来提高精度,但更多的是在间隔时间的上下文中。

另一种替代方案可以是线程以避免由系统运行循环引起的延迟。

对于我想做的事情,这被认为是“最佳”选择,还是我还应该关注其他什么? 或者NSTimer是否足够精确,如果我的应用中真的发生了很少的事情? 谢谢!

NSTimer绝对不是答案。 如果您想要任何精确度,我强烈建议您完全避免使用NSTimer

NSDate将返回一个NSTimeInterval ,它是一个具有sub ms精度的double。 NSTimeInterval以秒为单位,但它使用double来提供更高的精度。

斩波块上的下一个是CoreAnimation ,其function为CFAbsoluteTimeGetCurrent 。 许多人认为这比以前的选择更精确。 它不是更准确,也不是更精确。 同样令人困惑的是,此时间函数返回系统正常运行时间的值。 既然你试图准确地安排一些事情,那对你来说就没用了。

如果您真的需要更高的精度,唯一的答案是mach_absolute_time 。 花点时间了解这门课程。 这将以处理器相关的刻度返回给您的时间。 虽然它需要一些按摩来回到墙上时间,因为它实际上跟踪CPU周期,你不能比这更准确。

查看Apple关于精确计时和测量的技术说明 。

编辑:似乎你想在未来的某个指定点运行一些代码,我想到的第一个也是最简单的解决方案是UILocalNotifications。 它们可以毫不费力地处理时区和跟踪,因为fireDate是一个NSDate你应该看到与另一个NSDate相同的精度,并且比NSTimer更精确。

那么NSTimer的一个更好的替代品是GCD,你可以使用dispatch_after在一段时间后调用一个方法,它甚至更好。

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // TO DO METHOD CALL. }); 
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ double delayInSeconds = 0.2; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self doTimer]; }); }); - (void) doTimer { // your code } 

我的上一个项目遇到了同样的问题,这就是我解决它的方法。 首先,您需要节省从开始计算时间开始的时间。 就我而言,我选择使用NSDefault

 [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"ReminderStart"] 

然后,当您需要决定是否调用方法时,您将从NSDefault获取提醒开始时间,并使用它来与当前时间进行比较:

 NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *components = [gregorianCalendar components:NSMinuteCalendarUnit fromDate:REMINDER_START_DATE toDate:[NSDate date] options:0]; if (components.minute > 30){ //call your method here if the time difference is larger than 30 minutes } 

在我的代码中,我在几分钟内检查了时差,但如果你愿意,你可以将其完全调整为秒,小时,天或周。 希望这会有所帮助。