Swift에서 딜레이 후 코드 호출하기
이 글에서는 Swift에서 UI를 멈추지 않게 하면서 특정 시간 동안 기다린 후 비동기로 코드를 실행시키는 방법 일부를 정리한다. 모든 방법이 아닌 개인적인 선호로 골랐다는 점에 주의하자.
타이머를 사용해 딜레이 후 호출하기
어쩌면 가장 직관적인 방법으로 Timer
를 이용하는 방법이 있다. Objective-C에서는 NSTimer
라 불리는 클래스와 동일하다.
Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
print("3 seconds have passed")
}
타이머를 생성해서 돌리는 방법은 여러가지가 있지만 위의 방식이 가장 편한 것 같았다. 필요하다면 반복(repeats)도 지정할 수 있으니 딜레이 말고도 여러 용도로 쓸 수도 있다.
GCD를 이용해 딜레이 후 호출하기
GCD(Grand Central Dispatch)의 디스패치 큐에는 asyncAfter
라는 용도에 딱 맞는 메서드가 제공된다.
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
print("3 seconds have passed")
}
asyncAfter
의 경우 딜레이 시간을 정의할 때 약간 난해할 수도 있는데 DispatchTime.now()
를 알고 있다면 크게 어려울 것 없이 쓸 수 있다.
다만 위 코드는 메인 스레드에서 동작하는 만큼 동작하는 코드에 따라 UI에 영향을 줄 수도 있으니 아래와 같이 글로벌 큐를 이용하는 방식이 적절하지 않을까 생각된다.
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
DispatchQueue.main.async {
print("3 seconds have passed")
}
}
이렇게 하면 기다리는 동안 다른 일을 더 해도 UI에 큰 무리를 안 주면서 원하는 대로 동작한다. 다만 UI에 영향을 끼치는 코드는 메인 스레드에서 돌아가도록 주의해야 하는 점은 잊지 말자.
물론 위의 방식들이 정석에 가깝지만, 좀 더 단순하게 하려면 아래와 같이 그냥 쉬었다가(sleep) 하는 방법도 있다.
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 3)
DispatchQueue.main.async {
print("3 seconds have passed")
}
}
글로벌 디스패치큐는 백그라운드 스레드에서 돌아가기 때문에 사용할 수 있는 단순한 코드다. 사람에 따라 '무식한' 방법이라고 평가할 수도 있겠지만 어떻게 보면 특징이나 용도를 잘 활용한 기능으로 볼 수도 있어서 '단순한' 방법이라 표현하는 게 맞을 것 같다. 어쨌든 잘 동작하고 별 문제도 없으니 말이다.
Task
Swift Concurrency 지원으로 추가된 비동기 루틴을 지원하는 Task
를 활용하면 역시 쉬었다가 처리하는 방식의 '단순한' 방법을 쓸 수도 있다.
Task {
try await Task.sleep(nanoseconds: 3000000000)
print("3 seconds have passed")
}
Task
기반은 취소가 가능하다는 장점이 있다. 태스크 취소를 하려면 아래와 같이 해당 태스크 인스턴스에서 cancel()
메서드를 호출해 주면 된다. 다만 이 글의 주제에서 벗어나기 때문에 더 자세한 소개는 생략한다.
let delayedTask = Task {
try await Task.sleep(nanoseconds: 300000000000)
print("300 seconds have passed")
}
...
// 해당 태스크를 취소해야 할 필요가 있을 때
delayedTask.cancel()
태스크 내에서의 딜레이(sleep) 명령으로 Thread.sleep()
을 쓸 수 있는지는 잘 모르겠지만, 취소를 위해서는 반드시 Task.sleep()
을 써야 한다는 것 정도만 알아두자.
사족
GCD를 이용할 수 있으니 당연히 Thread나 OperationQueue를 이용할 수도 있지 않겠나라고 할 수도 있는데 맞다. 사실 이 둘도 위의 예와 거의 동일한 동작을 만들 수 있다. 하지만 가장 심플한 예는 아무래도 위에서 거론한 방식들 같다. 즉 이 외에도 여러 방법이 있을 수도 있으니 상황에 맞는 특수한 방법은 직접 찾아보자.