코코아에서 시스템 시계가 중간에 변경되었을 때조차도 두 지점 사이의 초 수를 계산합니다.

StackOverflow https://stackoverflow.com/questions/1627764

문제

타임 스탬프를 사용하여 화면에 어떤 시간이 표시되는지에 대한 통계를 계산하는 Cocoa OS X (Leopard 10.5+) 최종 사용자 프로그램을 작성하고 있습니다. 프로그램이 반복되는 NSTIMER를 사용하여 실행되는 동안 시간은 주기적으로 계산됩니다. [NSDate date] 타임 스탬프를 캡처하는 데 사용됩니다. 시작 그리고 마치다. 두 날짜의 차이를 몇 초 만에 계산하는 것은 사소한 일입니다.

최종 사용자 나 NTP가 시스템 클록을 변경하면 문제가 발생합니다. [NSDate date] 시스템 시계에 의존하므로 변경되면 마치다 변수는 시작, 시간 계산을 크게 엉망으로 만들었습니다. 내 질문:

1. 사이의 시간을 정확하게 계산할 수있는 방법 시작 그리고 마치다, 시스템 시계가 중간에 변경 되더라도 몇 초 만에?

그 이후로 몇 초가 지나간 수를 계산할 수 있으므로 변경하지 않는 기준점이 필요하다고 생각합니다. 예를 들어, 시스템 가동 시간. 10.6 - (NSTimeInterval)systemUptime, 부분의 NSProcessInfo, 시스템 가동 시간을 제공합니다. 그러나 내 앱이 10.5에서 작동해야하므로 작동하지 않습니다.

Nstimer를 사용하여 시간 카운터를 만들려고했지만 정확하지 않습니다. NSTIMER에는 여러 가지 실행 모드가 있으며 한 번에 하나만 실행할 수 있습니다. NSTIMER (기본적으로)에 들어갑니다 기본 실행 모드. 사용자가 충분한 시간 동안 UI를 조작하기 시작하면 nseventTrackingRunLoopMode 그리고 건너 뜁니다 기본 Nstimer 발사가 건너 뛸 수있는 실행 모드는 몇 초를 계산하는 데 부정확 한 방법입니다.

또한 NSTIMER 2 차 카운터를 실행하여 UI 상호 작용에서 멀리 떨어진 별도의 스레드 (NSRUNLOOP)를 작성하는 것에 대해 생각했습니다. 그러나 나는 멀티 스레딩을 처음 접했고 가능하다면 그로부터 멀리하고 싶습니다. 또한 CPU가 다른 애플리케이션 (큰 이미지 등을 렌더링하는 등)에 의해 CPU가 페그를받는 경우에 이것이 정확하게 작동하는지 확실하지 않습니다. Nstimer.

도움이 주셔서 감사합니다. :)

도움이 되었습니까?

해결책 3

나는 이것을 사용하는 방법을 알아 냈습니다. 가동 시간 () C 기능이 제공됩니다 <CoreServices/CoreServices.h>. 이것은 절대 시간 (CPU- 특이 적)을 반환하며, 이는 지속 시간 시간 (밀리 초 또는 나노초)으로 쉽게 변환 할 수 있습니다. 자세한 내용 : http://www.meandmark.com/timingpart1.html (가동 시간을위한 파트 3 아래를보십시오)

나는 얻을 수 없었다 mach_absolute_time() 제대로 작동하는 것은 지식이 부족하고 웹에서 많은 문서를 찾을 수 없기 때문에 가능성이 높습니다. 같은 시간을 잡는 것 같습니다 UpTime(), 그러나 그것을 두 배로 변환하면 나를 바보로 남겨 두었습니다.

[[NSApp currentEvent] timestamp] 응용 프로그램이 NSEVENTS를 받고있는 경우에만 작동했습니다. 신청서가 전경으로 들어간 경우 이벤트를받지 못하고 [[NSApp currentEvent] timestamp] 최종 사용자가 앱과 다시 상호 작용하기로 결정할 때까지 NSTIMER 발사 방법으로 동일한 오래된 타임 스탬프를 계속해서 계속 반환 할 것입니다.

모든 도움을 주셔서 감사합니다 Marc와 Mike! 당신은 분명히 답으로 이어지는 올바른 방향으로 나를 보냈습니다. :)

다른 팁

이 코드를 주도하는 것에 따라 두 가지 선택이 있습니다.

  • 절대적으로 정밀하게 사용하십시오 mach_absolute_time(). 기능을 불리는 지점 사이의 시간 간격을 정확하게 제공합니다.
  • 그러나 GUI 앱에서 이것은 종종 실제로 바람직하지 않습니다. 대신, 당신은 사이의 시차를 원합니다 이벤트 그것은 당신의 기간을 시작하고 끝냈습니다. 그렇다면 비교하십시오 [[NSApp currentEvent] timestamp]

좋아, 이것은 긴 샷이지만, 당신은 일종의 무언가를 구현할 수 있습니다. NSSystemClockDidChangeNotification 스노우 레오파드에서 제공됩니다.

이것은 이상한 아이디어이며 확실히 비 터미니즘이기 때문에 여기서 나와 함께 견뎌냅니다. 그러나 프로그램 기간 동안 Watchdog 스레드가 실행된다면 어떻게해야합니까? 이 스레드는 1 초마다 시스템 시간을 읽고 저장합니다. 논쟁을 위해 5 초 만에 만들어 봅시다. 따라서 5 초마다 이전 읽기를 현재 시스템 시간과 비교합니다. "충분히 큰"차이가 있다면 너무 많이 더 크게, 프로세스 일정 및 스레드 우선 순위 지정의 비결정주의를 설명하기 위해), 상당한 시간 변경이 있다는 알림을 게시합니다. 정확도 요구에 대해 "충분히 큰"값 (또는 시계가 이전에 재설정 된 경우 충분히 작음)을 구성하는 값을 퍼지해야합니다.

나는 이것이 일종의 해킹된다는 것을 알고 있지만 다른 해결책을 제외하고는 어떻게 생각하십니까? 그것이 당신의 문제를 해결할 수 있습니까?

편집하다

좋아, 원래 질문을 수정하여 멀티 스레딩을 처음 접했기 때문에 워치 독 스레드를 사용하지 않는다고 말합니다. 나는 당신이 편안한 것보다 조금 더 진보 된 일을하는 것에 대한 두려움을 이해하지만, 이것이 유일한 해결책이 될 수 있습니다. 이 경우 약간의 독서가있을 수 있습니다. =))

그렇습니다. Photoshop과 같은 것이 프로세서에서 쓰레기를 뽑는 것이 문제라는 것을 알고 있습니다. 또 다른 (더 복잡한) 솔루션은 워치 독을 갖지 않고 , 별도의 감시자가 있습니다 프로세스 그것은 최우선 과제 가므로 프로세서 페깅에 조금 더 면역적입니다. 그러나 다시, 이것은 정말로 복잡해지고 있습니다.

최종 편집

나는 완전성을 위해 다른 모든 아이디어를 위에 남겨 둘 것이지만, 시스템의 가동 시간을 사용하는 것도 이것을 다루는 유효한 방법 인 것 같습니다. 부터 [[NSProcessInfo processInfo] systemUptime] 10.6+에서만 작동하면 전화 할 수 있습니다 mach_absolute_time(). 그 기능에 액세스하기 위해 #include <mach/mach_time.h>. 그것은 반환 된 것과 같은 가치가되어야합니다 NSProcessInfo.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top