NSTimer 백그라운드 진입시 동작 분석

iOS에서 특정 시간주기로 특정 메서드을 호출하기위해 NSTimer를 사용하게 된다. 이때 앱이 백그라운드(background)로 진입할때, 그리고 잠시 후 다시 포어그라운드(foreground)로 돌아올경우 예약되어 사용중인 NSTimer가 어떻게 동작하는지 살펴보도록 하자.

기본적으로 타이머의 실행 주기는 타이머가 등록되는 시간을 기준으로하여 고정 간격으로 실행(fire)된다. 이는 앱이 백그라운드로 진입하면서 잠시 타이머가 정지한다 해도 영향을 받지않고 동일하게 적용된다.

백그라운드 진입시 NSTimer는 언제 정지하는가?

  1. 앱이 백그라운드로 진입하면서 AppDelegate의 applicationDidEnterBackground:가 호출될 때, 특별히 명시적으로 backgroundTask를 등록하지 않은경우에는 백그라운드 진입과 동시에 타이머는 정지하게된다.

  2. 앱이 백그라운드로 진입하더라도 명시적으로 backgroundTask가 등록되어 실행중인 동안에는 앱이 포어그라운드에 있을때와 동일하게 타이머가 계속 fire된다. 하지만 backgroundTask가 끝나거나, 허용된 task 실행 시간이 만료된 경우에 타이머는 정지하고, 1번과 동일하게 동작한다.

다시 포어그라운드 진입시 NSTimer는 어떻게 fire되는가?

포어그라운드로 진입하는 경우에 발생하는 경우의 수는 다음 3가지이다.

  1. 타이머 시간주기 경과전에 진입
    • 타이머 fire되지 않고있다가 다음 예약된 시간에 fire
  2. 타이머 시간주기 1번 경과 후 진입
    • 진입시 바로 타이머 한번 fire. 다음 예약된 시간에 다시 fire
  3. 타이머 시간주기 2번이상 경과 후 진입
    • 아무리 많은 시간 주기가 경과했어도 진입시에 바로 한번만 타이머가 fire. 다음 예약된 시간에 다시 fire

좀더 쉬운 이해를 위해 다음 예시를 보자.

NSTimer 동작 예시

타이머 시간주기 20초 설정

처음 타이머가 fire되어 코드가 실행된 시점을 0:00[분:초] 라고 할때,

  • 0:00 fire
  • 0:20 fire
  • 0:40 fire
  • 0:45 백그라운드 진입 -> 타이머 정지
  • 1:50 포어그라운드 진입 -> 시간이 지나서 진입시 1번만 바로 fire
  • 2:00 fire (포어그라운드 진입하면서 fire된 후 20초 후에 다시 fire되는것이 아니라, 기존 처음 설정된 타이밍에서 20초간격 그대로 유지하면서 fire됨)