본문 바로가기

IOS

[IOS] User Event & MainRunLoop

프로젝트를 진행하는데 MainRunLoop에 관여하는 부분에 있어 버그가 발생했고 

이부분에 대해서 포스팅 하려 한다.

 

버그 발생 부분과 MainRunLoop에 대해서 알아보기 전에

선행으로 AppLifeCycle에 부분적으로 먼저 알고 가보도록 하겠다.

 

일단 사용자가 앱의 아이콘을 터치했을때 ( 앱을 시작할때 )

C언어 기반의 프로젝트는 main이라는 함수의 호출이 곧 앱의 시작이 된다.

IOS의 앱 또한 Object-C 기반임으로 main함수가 호출이 된다.

다만 UIKit framework에서 main함수를 관리 하기 때문에 

개발자는 따로 main에 관여해주지 않아도 된다. 

 

그리고 UIKit framework에서 main을 호출 하면서 UIApplicationMain 함수를 호출 하는데이 과정을 통해서 UIApplication 객체가 생성이 된다.그리고 이 객체의 싱글톤인 shared를 통해서 앱의 실행 프로세스에 부분적으로 접근하여 관리할 수 있다. ( 앱이 Background로 진입할때,  푸시알람 수신시 등등)

 

다시 정리하자면 앱 실행 -> UIKit framework에서는 main을 호출 ->  UIApplicationMain을 호출-> UIApplication 객체 생성

 

ㅇㅣ런 과정이 있고 추가적으로 UIApplication은 MainRunLoop을 실행 시킨다.

MainRunLoop 이라는 것은 작업을 스케쥴링하거나,

전달되는 이벤트를 조정하기 위해 사용하는 이벤트 처리 루프,

유저의 이벤트 들을 처리하는 프로세스다.

UIApplication은 MainRunLoop를 View와 관련된 이벤트 View의 업데이트에 활용한다. ( Main thread에서 실행)

 

 

 

유저가 이벤트를 발생시키면

Operating system에 의해 이벤트가 생성되고

MainRunLoop이 유저의 이벤트를 처리한다.

UIApplication 객체는 이때 가장 먼저 이벤트를 받고 어떤 것이 실행되야 하는지 결정한다.

 

이 포스팅의 키워드는 MainRunLoop이다.

간단히 MainRunLoop에 대해서 알아보았고 

경험했던 버그에 대해서 얘기해보자면

 

상단에 View가 있었고 하단에는 TableView가 위치해 있었다.

그리고 상단 View에는 Timer의 호출로 인한 View의 update가 지속적으로 발생하고 있는 상황.

 

문제는 TableView의 scroll 이벤트를 진행했을때 

Timer의 selector 메소드가 호출이 되지 않는 상황이 생겨버렸다.

 

원인은 TableView에 scroll이 발생했을때

RunLoop는 TableView scroll에 대한 이벤트를 처리했고

Timer의 호출로 인한 View 이벤트 처리가 뒷전으로 밀려버리는 상황이 되버린거같다.( 틀렸다면 댓글달아주시면 감사하겠슴당 )

 

이와 같은 증상을 겪는 개발자들이 몇몇 있었느지

이 문제에 대한 Stackoverflow 답변이 있었고

 

stackoverflow.com/questions/12145007/scrolling-an-uitableview-will-stop-timer

 

Scrolling an UITableView will stop Timer

I'm a beginner and I'm trying to write and application for iOS that will show to the user in the main screen a timer from 25 minutes to 0 (made of a UILabel whom text is updated every second using an

stackoverflow.com

 

코드를 보자면 이렇다.

RunLoop의 current에 접근하게 되면 현재 Thread의 실행 루프를 반환하게 되고 

add 라는 메소드를 사용할 수 있게 된다.

그리고 첫번째 파람에 Timer를 넣고 두번째 파람에 common을 넣고 호출 하게 되면 

Timer가 현재 Thread의 실행 루프에 추가되어 공동?? 으로 RunLoop에서 같이 실행되어서 그런지

Scroll 이벤트가 추가되어서 발생했던 Timer가 중단되는 버그는 더이상 발생하지 않았다.

 

self.updateTimer = Timer.scheduledTimer(timeInterval:1.0, target: self, selector: Selector(("updateFunction")), userInfo: nil, repeats: true)
RunLoop.current.add(self.updateTimer, forMode: RunLoopMode.common)