Timer

Panther·2021년 9월 25일
0

https://developer.apple.com/documentation/foundation/timer

"A timer that fires after a certain time interval has elapsed, sending a specified message to a target object."

특정 시간 인터벌이 경과한 후에 타깃 객체에 구체화된 메시지를 보내면서 울리는 타이머입니다.

Declaration

class Timer : NSObject

Overview

타이머는 런루프와 함께 동작합니다. 런루프는 타이머에 대해 강한 참조를 유지하기 때문에 런루프에 타이머를 추가한 후 강한 참조를 유지할 필요가 없습니다.

타이머를 효과적으로 사용하려면 런루프 동작 방법을 인식하고 있어야 합니다. 더 많은 정보는 Threading Programming Guide를 보시기 바랍니다.

Threading Programming Guide
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html#//apple_ref/doc/uid/10000057i

타이머는 실시간 메커니즘이 아닙니다. 타이머의 울림 시간이 긴 런루프 콜아웃 동안 발생하거나 런루프가 타이머를 모니터링하지 않는 모드에서 발생하면, 타이머는 런루프가 다음에 타이머를 확인하기까지 울리지 않습니다. 그러므로 타이머가 울리는 시점인 실제 시간은 나중이될 수 있습니다. Timer Tolerance 또한 보시기 바랍니다.

Timer Tolerance는 이 글의 아래애 나옵니다.

타이머는 코어 파운데이션 카운터파트, CFRunLoopTimer에 톨프리로 브릿지됩니다. 더 많은 정보는 Toll-Free Bridging을 보시기 바랍니다.

Comparing Repeating and Nonrepeating Timers

타이머가 생성 시점에 반복될지 혹은 반복되지 않을지를 구체화할 수 있습니다. 반복하지 않는 타이머는 한 번만 울리며, 이후 자동으로 무효화되고 다시 울리는 것을 방지합니다. 반대로 반복 타이머는 울린 후 같은 런루프에서 스스로 다시 스케줄링됩니다. 반복 타이머는 항상 스케줄된 울림 시간에 기반해 스스로 스케줄링됩니다. 예를 들어 타이머가 특정 시간에 울리기 위해 스케줄링되고, 이후 5초마다 울리기로 스케줄링되면, 스케줄링된 울림 시간은 항상 원래의 5초 시간 인터벌이 되며, 실제 울림 시간이 지연될 때에도 그렇습니다. 울리는 시간이 스케줄링된 울림 시간의 하나 혹은 하나 이상을 통과해서 지연되는 경우 타이머는 해당 시간 간격에 한 번씩만 울립니다. 타이머는 울린 이후 다시 스케줄링되며, 미래의 다음 스케줄링된 울리는 시간에 대해 그렇습니다.

Timer Tolerance

iOS 7 및 이후 버전, macOS 10.9 및 이후 버전에서 타이머(tolerance)에 대한 허용 오차를 지정할 수 있습니다. 타이머가 울릴 때 이와 강튼 유연성은 향상된 전력 절약 및 반응성을 최적화하기 위한 시스템의 기능을 향상시팁니다. 타이머는 스케줄링된 울림 날짜 및 스케줄링된 날짜에 허용 오차를 더한 것 가시 어느 때에서나 울릴 수 있습니다. 타이머는 스케줄링된 울림 날짜 전에 울리지는 않습니다. 반복하는 타이머의 경우 다음 울리는 날짜는 개별 울리는 시간에 적용된 허용 오차와 상관없이 기존 울림 날짜로부터 계산됩니다. 기본값은 0이며, 추가적인 허용 오차 적용이 되지 않는다는 것을 의미합니다. 시스템은 허용 오차 속성의 값과 상관없이 특정 타이머의 작은 허용 오차를 적용할 권리를 갖고 있습니다.

타이머의 사용자로써 타이머에 대한 적합한 허용 오차를 결정할 수 있습니다. 일반적인 규칙은 반복되는 타이머의 경우 인터벌의 적어도 10%에 해당하는 허요 오차를 설정하는 것입니다. 허용 오차의 작은 양이더라도 애플리케이션 사용 전력에 긍정적인 영향을 미칠 수 있습니다. 시스템은 허용 오차에 대한 최대값을 강제할 것입니다.

Scheduling Timers in Run Loops

한 번에 오직 하나의 런 루프에서 타이머를 추가할 수 있으며, 해당 런루프 내부에서 여러 런루프 모드에 추가될 수 있을 때에도 그렇습니다. 타이머 생성에는 세 가지 방법이 있습니다.

  • 기본값 모드에서 현재 런루프에 타이머를 생성하고 타이머 스케줄링을 하려면 scheduledTimer(timeInterval:invocation:repeats:) 혹은 scheduledTimer(timeInterval:target:selector:userInfo:repeats:) 클래스 메소드를 사용할 수 있습니다.
  • 런루프에서 스케줄링 없으 타이머 객체를 생성하려면 init(timeInterval:invocation:repeats:) 혹은 init(timeInterval:target:selector:userInfo:repeats:) 클래스 메소드를 사용할 수 있습니다. (생성 후 상응하는 RunLoop 객체의 add(_:forMode:) 메소드를 호출해서 직접 런루프에 타이머를 추가해야 합니다.)
  • init(fireAt:interval:target:selector:userInfo:repeats:) 메소드를 사용해서 타이머 할당 및 초기화를 할 수 있습니다. (생성 후 상응하는 RunLoop 객체의 add(_:forMode:) 메소드를 호출해서 직접 런루프에 타이머를 추가해야 합니다.)

런루프에서 한 번 스케줄링 되면 타이머는 무효화될 때까지 구체화된 인터벌 내에서 울립니다. 반복하지 않는 타이머는 울린 후 스스로 즉시 무효화됩니다. 그러나 반복하는 타이머의 경우 invalidate() 메소드를 호출해서 직접 타이머 객체를 무효화해줘야 합니다. 이 메소드 호출은 현재 런루프로부터 타이머의 제거를 요청합니다. 결과적으로 타이머가 설치되었던 같은 스레드로부터 invalidate() 메소드를 항상 호출해야 합니다. 타이머를 무효화시키는 것은 즉시 타이머를 무효화하며, 이는 더 이상 런루프에 영향을 주지 않게 됩니다. 런루프는 이후 타이머를 제거(그리고 타이머가 가지고 있었던 강한 참조)하며, invalidate() 메소드 반환 전 혹은 이후 특정 지점에서 그렇게 합니다. 무효화되면 타이머 객체는 재사용될 수 없습니다.

반복 타이머가 울린 후 타이머는 구체화된 허용 오차 내에서 마지막으로 스케줄링된 울림 날짜 이후 타이머 인터벌의 인티저 여럿인 가장 가까운 미래 시점으로 다음 울림을 스케줄링합니다. 셀렉터 혹은 호출을 수행하기 위해 호출하는 시간이 구체화된 인터벌보다 긴 경우 타이머는 다음 울림만을 스케줄링합니다. 즉 타이머는 구체화된 셀렉터 혹은 호출을 호출하는 동안에 발생해야 했었던 놓친 울림에 대한 어떠한 보상도 시도하지 않습니다.

Subclassing Notes

타이머는 서브클래싱하지 않아야 합니다.

Topics


Firing Messages as a Combine Publisher

Timer.TimerPublisher

주어진 인터벌에서 현재 날짜를 반복해서 보내는 퍼블리셔입니다.

https://developer.apple.com/documentation/foundation/timer/timerpublisher
https://velog.io/@panther222128/Timer.TimerPublisher


0개의 댓글