25

我正在尝试设计一个发生实时事件的系统,并且我想将它们与时钟同步。 [NSDate date]通常没问题,但用户可以更改此设置并欺骗系统。我所需要的只是一个可以从中获取相对时间的时钟(例如 64 位计数器)——我不需要绝对时间(或一天中的时间等)。

我可以使用这样的 API 吗?

编辑:我还想补充一点,这个时钟需要在应用程序的会话中保持不变。

4

6 回答 6

10

iPhone 上最好的单调递增数字是mach_absolute_time()自上次重启以来的 CPU 滴答计数。如果您出于任何原因想要在几秒钟内获得它,最容易使用CACurrentMediaTime().

使用它来创建“始终递增”非常容易。首次启动时,将当前值存储在您喜欢的任何位置。当您退出时,并定期保存该值的偏移量。重启时,检查当前值;如果它小于您以前的基本值,请替换您的基本值(已重新启动)。

当然,所有这些都可以通过删除你的应用程序来清除,除非你在服务器上存储了一些东西。

请注意,这不能用作强大的安全措施。没有办法阻止授权用户伪造请求。因此,取决于您所说的“欺骗系统”,这可能不是一个可解决的问题。您能做的最好的事情就是不断努力寻找黑客并与他们打交道。

于 2012-07-10T13:05:49.687 回答
8

如果您只需要一个时钟来测量单调递增的事件,您只需获取当前系统正常运行时间 ala 即可clock_gettime(CLOCK_MONOTONIC)。如果重启设备有问题,只需保存上次使用的值,并在下次启动时使用上次保存的值作为偏移量。这里的问题可能是,如果他们真的关闭了设备,它就不会计算那个时间。但是,如果您担心用户会加快时间,他们就不能这样做,只能放慢速度。

于 2012-07-10T13:08:36.940 回答
6

我在我们的应用程序中使用它

+ (NSDate *) getAWSDate
{
    NSDate *today = nil; 
   NSString *dateString = nil;

    NSString *awsURL = @"http://s3.amazonaws.com";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:awsURL]];  
    [request setHTTPMethod:@"HEAD"];  

    NSHTTPURLResponse *response;  
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: NULL];  

    if ([response respondsToSelector:@selector(allHeaderFields)]) {  
        dateString = [[response allHeaderFields] objectForKey:@"Date"];
        dateString = [dateString stringByReplacingOccurrencesOfString:@"GMT" withString:@"+0000"];
        NSDateFormatter *df = [[NSDateFormatter alloc] init];  
    df.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss z";
    df.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];  
    df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];  
    today = [df dateFromString:dateString];
    [df release];    
    }           
    return today;
}
于 2012-07-10T13:46:17.657 回答
5

我想mach_absolute_time()可能是你想要的。这里有很多信息:http: //developer.apple.com/library/mac/#qa/qa1398/_index.html

它基本上是自设备启动以来滴答数的计数器。这将在重新启动时重置,但除此之外它是一个单调递增的计数器。

如果计数器自上次(设备重新启动)以来减少,您可以保留计数器的最后一个值并处理它。在这种情况下,您可以将最后一个已知值添加到当前值以获得已过去时间的下限,您所失去的只是最后一次会话和设备关闭之间的时间,您将保持之间的时间重启和下一个会话。

于 2012-07-10T13:03:15.193 回答
3

据我所知,没有任何其他方法可以获得正确的时间。我会使用NTP。

网络时间协议 (NTP)是一种网络协议,用于通过分组交换、可变延迟数据网络同步计算机系统的时钟。更多:http ://en.wikipedia.org/wiki/Network_Time_Protocol

在一个项目中,我将使用NTP(我明天),但我已经做了一些研究:

iOS 库: https ://github.com/jbenet/ios-ntp - 作者注释:实施并不像那些 RFC 中描述的那样严格,因为目标是将时间精度提高到一秒,而不是几分之一毫秒.

对于非商业项目,请查看:www.packages.ubuntu.com/source/lucid/ntp

C 库: www.hillstone-software.com/hs_ntp_details.htm

文档: www.nist.gov/pml/div688/grp40/its.cfm

于 2012-07-10T12:58:11.010 回答
1

我能想到的唯一想法是使用 NTP 服务器来获取时钟,但这需要网络连接。

于 2012-07-10T12:54:28.593 回答