[iphone] Objective-C에서 예를 들어 밀리 초 단위로 정확한 시간을 어떻게 얻을 수 있습니까?
매우 정확하게 시간을 얻는 쉬운 방법이 있습니까?
메서드 호출 간의 지연을 계산해야합니다. 보다 구체적으로 UIScrollView에서 스크롤 속도를 계산하고 싶습니다.
답변
NSDate
그리고 timeIntervalSince*
메소드는 반환 NSTimeInterval
밀리 초 이하의 정확도로 이중 인을. NSTimeInterval
초 단위이지만 더 큰 정밀도를 제공하기 위해 double을 사용합니다.
밀리 초 시간 정확도를 계산하기 위해 다음을 수행 할 수 있습니다.
// Get a current time for where you want to start measuring from
NSDate *date = [NSDate date];
// do work...
// Find elapsed time and convert to milliseconds
// Use (-) modifier to conversion since receiver is earlier than now
double timePassed_ms = [date timeIntervalSinceNow] * -1000.0;
을 사용하여이 간격을 계산하는 다른 많은 방법이 있으며 NSDate Class ReferenceNSDate
에있는 클래스 문서를 참조 NSDate
하는 것이 좋습니다 .
답변
mach_absolute_time()
정확한 측정을 위해 사용할 수 있습니다.
참조 http://developer.apple.com/qa/qa2004/qa1398.html를
또한 볼 수 있습니다 CACurrentMediaTime()
본질적으로 같은 일을하지만, 사용하기 쉬운 인터페이스이다.
(참고 :이 답변은 2009 년에 작성되었습니다. clock_gettime()
최신 버전의 macOS 및 iOS에서 사용할 수있는 더 간단한 POSIX 인터페이스에 대한 Pavel Alexeev의 답변을 참조하십시오 .)
답변
사용하지 마십시오 NSDate
, CFAbsoluteTimeGetCurrent
또는 gettimeofday
경과 시간을 측정 할 수 있습니다. 이들은 모두 시스템 시계에 의존하며, 이는 네트워크 시간 동기화 (NTP) 시계 업데이트 (드리프트를 조정하기 위해 자주 발생 함), DST 조정, 윤초 등과 같은 다양한 이유로 인해 언제든지 변경 될 수 있습니다 .
즉, 다운로드 또는 업로드 속도를 측정하는 경우 실제로 발생한 일과 관련이없는 수치가 갑자기 급증하거나 감소하게됩니다. 성능 테스트에는 이상하게 잘못된 이상 값이 있습니다. 잘못된 기간이 지나면 수동 타이머가 트리거됩니다. 시간은 뒤로 갈 수도 있고 음의 델타로 끝날 수 있으며 무한 재귀 또는 데드 코드로 끝날 수 있습니다 (예,이 두 가지를 모두 수행했습니다).
사용 mach_absolute_time
. 커널이 부팅 된 이후의 실제 시간을 측정합니다. 단조롭게 증가하며 (뒤로 이동하지 않음) 날짜 및 시간 설정의 영향을받지 않습니다. 작업하는 것이 고통스럽기 때문에 다음을 제공하는 간단한 래퍼가 있습니다 NSTimeInterval
.
// LBClock.h
@interface LBClock : NSObject
+ (instancetype)sharedClock;
// since device boot or something. Monotonically increasing, unaffected by date and time settings
- (NSTimeInterval)absoluteTime;
- (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute;
@end
// LBClock.m
#include <mach/mach.h>
#include <mach/mach_time.h>
@implementation LBClock
{
mach_timebase_info_data_t _clock_timebase;
}
+ (instancetype)sharedClock
{
static LBClock *g;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
g = [LBClock new];
});
return g;
}
- (id)init
{
if(!(self = [super init]))
return nil;
mach_timebase_info(&_clock_timebase);
return self;
}
- (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute
{
uint64_t nanos = (machAbsolute * _clock_timebase.numer) / _clock_timebase.denom;
return nanos/1.0e9;
}
- (NSTimeInterval)absoluteTime
{
uint64_t machtime = mach_absolute_time();
return [self machAbsoluteToTimeInterval:machtime];
}
@end
답변
CFAbsoluteTimeGetCurrent()
A와 절대 시간 반환 double
값을,하지만 난 정밀도가 무엇인지 모르는 -이 있습니다 매 수십 밀리 초를 업데이트하거나 모든 마이크로를, 나도 몰라 업데이트 할 수 있습니다.
답변
mach_absolute_time()
틱 (아마 가동 시간)을 사용하여 절대 시간 동안 커널과 프로세서의 조합을 쿼리 하기 때문에 사용하지 않을 것입니다.
내가 사용하는 것 :
CFAbsoluteTimeGetCurrent();
이 기능은 iOS 및 OSX 소프트웨어 및 하드웨어의 차이를 수정하도록 최적화되어 있습니다.
더 괴짜
차이의 지수 mach_absolute_time()
와는 AFAbsoluteTimeGetCurrent()
항상 주위 24000011.154871입니다
다음은 내 앱의 로그입니다.
최종 결과 시간에 차이가 있음을하시기 바랍니다 노트 CFAbsoluteTimeGetCurrent()
의이
2012-03-19 21:46:35.609 Rest Counter[3776:707] First Time: 353900795.609040
2012-03-19 21:46:36.360 Rest Counter[3776:707] Second Time: 353900796.360177
2012-03-19 21:46:36.361 Rest Counter[3776:707] Final Result Time (difference): 0.751137
2012-03-19 21:46:36.363 Rest Counter[3776:707] Mach absolute time: 18027372
2012-03-19 21:46:36.365 Rest Counter[3776:707] Mach absolute time/final time: 24000113.153295
2012-03-19 21:46:36.367 Rest Counter[3776:707] -----------------------------------------------------
2012-03-19 21:46:43.074 Rest Counter[3776:707] First Time: 353900803.074637
2012-03-19 21:46:43.170 Rest Counter[3776:707] Second Time: 353900803.170256
2012-03-19 21:46:43.172 Rest Counter[3776:707] Final Result Time (difference): 0.095619
2012-03-19 21:46:43.173 Rest Counter[3776:707] Mach absolute time: 2294833
2012-03-19 21:46:43.175 Rest Counter[3776:707] Mach absolute time/final time: 23999753.727777
2012-03-19 21:46:43.177 Rest Counter[3776:707] -----------------------------------------------------
2012-03-19 21:46:46.499 Rest Counter[3776:707] First Time: 353900806.499199
2012-03-19 21:46:55.017 Rest Counter[3776:707] Second Time: 353900815.016985
2012-03-19 21:46:55.018 Rest Counter[3776:707] Final Result Time (difference): 8.517786
2012-03-19 21:46:55.020 Rest Counter[3776:707] Mach absolute time: 204426836
2012-03-19 21:46:55.022 Rest Counter[3776:707] Mach absolute time/final time: 23999996.639500
2012-03-19 21:46:55.024 Rest Counter[3776:707] -----------------------------------------------------
답변
#define CTTimeStart() NSDate * __date = [NSDate date]
#define CTTimeEnd(MSG) NSLog(MSG " %g",[__date timeIntervalSinceNow]*-1)
용법:
CTTimeStart();
...
CTTimeEnd(@"that was a long time:");
산출:
2013-08-23 15:34:39.558 App-Dev[21229:907] that was a long time: .0023
답변
또한 NSNumber
CoreData에 저장하려는 경우 Unix epoch (밀리 초)로 초기화 된 64 비트를 계산하는 방법도 있습니다. 이런 방식으로 날짜를 저장하는 시스템과 상호 작용하는 내 앱에 필요했습니다.
+ (NSNumber*) longUnixEpoch {
return [NSNumber numberWithLongLong:[[NSDate date] timeIntervalSince1970] * 1000];
}