[ios] setNeedsLayout vs layoutIfNeeded

Main Run Loop

앱이 실행되면 iOS의 UIApplication이 메인 스레드에서 main run loop를 실행시킵니다. main run loop는 돌아가면서 터치 이벤트, 위치의 변화, 디바이스의 회전 등의 각종 이벤트들을 처리하게 됩니다. 이러한 처리 과정은 각 이벤트들에 알맞는 핸들러를 찾아 그들에게 처리를 위한 권한을 위임하여 진행하게 된다.

버튼의 터치 이벤트를 @IBAction 메서드가 처리하는 것과 같다.

이렇게 발생한 이벤트들을 모두 처리하고 권한이 다시 main run loop로 돌아오게 되고 이 시점을 update cycle이라고 합니다.

Update Cycle

main run loop에서 이벤트가 처리되는 과정에서 버튼을 누르면 크기나 위치가 이동하는 애니메이션과 같이 layout이나 position 값을 바꾸는 핸들러가 실행될 때도 있다. 이러한 변화는 즉각적으로 반영되는 것이 아닙니다.

시스템은 이러한 layout, position이 변화되는 View를 체크합니다. 그리고 모든 핸들러가 종료되고 main run loop로 권한이 다시 돌아오는 시점인 update cycle에서 이런 View들의 값을 바꿔주어 position이나 layout의 변화를 적용시킵니다.

즉, Position이나 layout의 값을 변경하는 코드와 실제로 변경된 값이 반영되는 시점에는 시간차가 존재한다는 뜻입니다.

이러한 시간차가 존재한다는 것을 알고 있어야! setNeedsLayout과 layoutIfNeeded의 차이를 알 수 있습니다.

스크린샷 2023-10-16 12.52.38.png

이렇게 시간차가 존재하지만 이 시간차는 사용자가 체감할 수 없을 정도로 짧기 때문에 사용자는 이 시간차를 느끼지 못합니다. 하지만 개발하는 사람은 이런 시간차를 인지하고 있어야 정확히 원하는 핸들러를 구현할 수 있습니다.