안녕하세요! 후르륵짭짭입니다.
일주일만에 글을 올리게 됐는데요,,,
최근에 마냥 행복한 일만 있는게 아니였고,,, 기말고사여서
글을 자주 올리기에는 어려움이 쫌 있었습니다.
그럼 이번에 공부한 것을 올려 보도록 하겠습니다.
Timer라는 것인데요.
우리가 반복적인 애니메이션을 보여줄 때, 유용하게 사용 할 수 있을것 같습니다.
(할게 참 많은거 같습니다 ㅠㅠ)
** What is Timer **
Timer의 정의를 보면 특정한 시간 간격이 지난 후에 발생하는 것이 라고 정의 되어 있습니다.
이게 무슨 말이고 하면,,, 그냥 특정 시간 지나면 작동하는 거 라고 생각하시면 됩니다.
이게 쫌 중요한 말인데,, Timer는 Run Loop랑 결합되어 작동한다라고 적혀 있습니다. 그리고 Run Loop는 Timer랑 강한 관계를 유지하기 때문에 Timer를 인위적으로 유지 할 필요 없다고 되어 있습니다.
그러면 Run Loop를 한번 살펴 보도록 하겠습니다.
developer.apple.com/documentation/foundation/runloop
Run Loop는 input를 관리하는 매개체 입니다.
아직 잘 이해가 안되는데,,,
이것을 보면 RunLoop 객체는 마우스나 키보와 같은 입력 소스를 진행한다고 되어 있습니다.
이 말은 Thread를 사용한다는게 추측이 되죠?
역시 내용을 보면 각각의 Main Thread를 포함한 Thread 객체는 자동적으로 RunLoop를 가지고 있다고 되어 있습니다.
그러니깐 화면을 관리하는 Main Thread도 RunLoop가 있고 이 RunLoop가 입력값을 관리하는 것을 알 수 있습니다.
그런데 이 내용을 보면 RunLoop의 관점에서 보면 Timer객체는 입력이 아니라 특별한 타입이라고 되어 있습니다. 그리고 그 말은 RunLoop는 Timer를 반환하지 않는다고 되어 있습니다.
흠,,, 위에서 Timer는 RunLoop랑 관련되어 있는데 Timer는 입력이 아니라 반환되지 않는다고 하면,,,, RunLoop는 Timer를 관리하지 않는 것을 의미하는 것으로 생각하면 될 것 같습니다.... (나중에 좀더 자세하게 알아보도록 하겠습니다 ㅠㅠ )
** Timer 기본적인 사용 방법 **
지금 까지 Timer가 무엇인지 RunLoop는 무엇인지 알아봤습니다...
아직 완벽하지 않지만,,, 내용을 쭉 정리 해보도록 하겠습니다.
Timer는 일단 특정 시간이 지나면 작동 된다고 정의 되어 있습니다.
그래서 Timer에는 시간이 들어가야한다는 것을 추측할 수 있습니다.
그럼 사용방법을 알아보도록 하겠습니다.
방법은 총 두가지가 있습니다.
- selector를 사용하는 방법 -
let temp = Timer.scheduledTimer(timeInterval: 시간 간격,
target: 작동할 객체,
selector: #selector(작업 수행 objc 함수),
userInfo: 보낼 정보,
repeats: 반복여부)
Timer객체 안에는 scheduledTimer()가 있는데 여기에 select는 보낼 데이터가 있을 때 사용합니다.
- Closure를 사용하는 방법 -
let temp = Timer.scheduledTimer(withTimeInterval: 시간간격, repeats: 반복여부) {(Timer) in }
Timer.scheduledTimer() 함수를 보면 위에 select와 큰 차이가 없지만 훨신 간결하게 사용 할 수 있습니다.
따라서 함수에 함께 보낼 데이터가 없다면 closuer 방식의 Timer.scheduledTimer를 더 선호 하는 것 같습니다.
그러면 select 함수를 사용하는 방법을 더욱 깊게 보도록 하겠습니다.
var userInfoTimer : Timer?{
let info : [String : String] = ["Hururuek" : "ChapChap"]
let temp = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(userInfofunc), userInfo: info, repeats: false)
return temp
}
@objc func userInfofunc(timer : Timer){
guard let userinfo = timer.userInfo else {
print("Nil userInfo")
return }
print(userinfo)
}
//실행 결과
{
Hururuek = ChapChap;
}
자 이 내용을 보면 일단 [String : String] 자료형을 가지는 info가 있고 temp = Timer.scheduledTimer()를 해줬습니다.
그리고 selector에 작동을 수행할 objc 함수를 넣어줍니다.
이 때 timer : Timer로 해주면서 자동으로 변수가 보내지게 됩니다.
그리고 timer.userInfo에 자료가 넘어간 것을 확인 할 수 있습니다. (코드 보면 바로 이해가 가죠???)
** 원격으로 Timer객체를 작동시키자 **
위에서 userInfoTimer Timer 인스턴스를 만들었는데 , 어떻게 하면 작동 시킬 수 있을지 궁금했습니다.
그래서 찾아보니, fire()라는 메소드가 있었습니다.
사용 방법은 너무 간단합니다. ㅎㅎㅎㅎ
@IBAction func letFire(_ sender: UIButton) {
//원격으로 작동 시킬 필요가 있을 때
singleTimer.fire()
userInfoTimer?.fire()
}
이렇게 버튼을 누르면 작동 시키고자 할 때, userInfo.fire()를 해주면 Timer 함수가 작동 됩니다.
** Timer 함수 작동 끄기 **
작동을 멈추는 방법은 더욱 간단합니다.
Timer인스턴스.invalidate()
이렇게 해주면 됩니다.
예를 들어 아래 처럼 일반적인 Timer.scheduledTimer가 있을 때, 아래 처럼 해주면 됩니다.
func callRepeatTimer(){
var cnt = 0
let calendar = Calendar.current
repeatTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) {
[weak self] (Timer) in
let date = Date()
let second = calendar.component(.second, from: date)
cnt += 1
print("Hello World \(second)")
if cnt >= 5{
//time를 멈추는 방법
self?.repeatTimer?.invalidate()
print("Stop Timer")
}
}
** Timer의 문제 두가지 **
Timer는 두가지 문제 점이 존재 합니다.
- 에너지 사용량이 많다 -
바로 무한 반복을 하기 때문에 매 시간 마다 작동한다는 것 입니다.
그러면 배터리 사용량이 증가하게 됩니다!
이 때 이 문제를 해결해 주는 것이 바로 Delay를 주는 것인데, 그 때 사용 하는 것이 tolerance 입니다.
repeatTimer?.tolerance = 특정시간
따라서 위에 처럼 Timer인스턴스.tolerance = 지체할 시간
을 주면 ( 반복 시간 + tolerance = 시간 )이렇게 됩니다.
- Main Thread 작동 문제 -
위에 영상을 보면 빨간색 뷰가 있고 그것이 ScrollView로 구성되어 있는 것을 확인 할 수 있습니다.
그런데 ScrollView를 만지고 있으면 Timer가 작동 하지 않는 것을 확인 할 수 있습니다. (직접 해보시면 알 겁니다 ㅎㅎㅎ)
이 문제는 위에서 설명한 것과 관련이 있는데요.
사용자 입력을 관리하는 RunLoop는 Timer와 깊은 관계가 있지만 Timer 객체에 대해서는 관리하지 않기 때문에 반환하지 않는다고 설명 했습니다.
따라서 MainThread의 RunLoop에서 사용자 입력 처리를 해줄 때, Timer는 제외해서 처리하게 되는 겁니다.
이렇기 때문에 Timer는 특정 사용자 처리가 발생하면 작동 하지 않는 것 입니다.
이러한 문제를 해결하기 위해
RunLoop.current.add(repeatTimer!, forMode: .common)
이렇게 코드를 넣어주시면, RunLoop에서 Timer객체를 추가하여 관리하게 됩니다.
지금 까지 Timer를 사용하는 방법에 대해 알아봤습니다.
모두 즐거운 코딩 하세요!!
전 기말고사 공부 하러 가겠습니다.
소스 코드 :
github.com/HururuekChapChap/Xcode_TestProj/tree/master/Timer_Tutorial/Timer_Tutorial
참고 사이트 :
Timer가 무엇인가?
developer.apple.com/documentation/foundation/timer
쓰레드링 프로그래밍에 대한 설명
아직 잘 사용법을 모르는 tolerance
developer.apple.com/documentation/foundation/timer/1415085-tolerance
Timer 가이드 북 주된 사용 방법
www.hackingwithswift.com/articles/117/the-ultimate-guide-to-timer
Timer에서 Fire() 가 머지?
developer.apple.com/documentation/foundation/timer/1414035-fire
현재 시간에 초를 출력하는 방법
medium.com/programming-with-swift/get-hours-minutes-and-seconds-from-date-with-swift-d11bdac4368c
꼭 공부 해야할 것 RunLoop가 머지?
jcsoohwancho.github.io/2019-09-01-스레드-프로그래밍(2)-RunLoop/
'Xcode > IOS' 카테고리의 다른 글
IOS) TableView의 Section을 다뤄보자 (0) | 2020.12.13 |
---|---|
IOS) 동적인 TableView Cell을 만드는 방법 (0) | 2020.12.12 |
IOS) Local Notification을 이용해보자 2부 (0) | 2020.11.25 |
IOS) Local Notification을 이용해보자 1부 (0) | 2020.11.22 |
IOS) PickerView 에 대해서 알아보자! (0) | 2020.11.12 |
댓글