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

时间:2014-04-04 14:51:27

标签: ios timer

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

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

我也看到提到使用CADisplayLink来提高精确度,但在interval timing的背景下更多。

另一个替代方案可能是threading,以避免系统运行循环造成的延迟。

被认为是最好的"选择我想做什么,或者我还应该看看其他什么?或者NSTimer是否足够精确,如果在我的应用程序中真的发生了很少的事情?谢谢!

4 个答案:

答案 0 :(得分:3)

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.
});

答案 1 :(得分:2)

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

NSDate并返回NSTimeInterval,这是一个具有亚毫秒精度的双精度。 NSTimeInterval以秒为单位,但它使用双精度来提高精度。

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

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

查看Apple's Tech Note on Precise Timing and Measurements

编辑:看起来您希望将来在指定的位置运行一些代码,我想到的第一个也是最简单的解决方案是UILocalNotifications。他们可以毫不费力地处理时区和跟踪,因为fireDateNSDate,您应该看到与NSDate相同的精度,并且 比{{1}更精确}}

答案 2 :(得分:1)

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 
}

答案 3 :(得分:0)

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

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