Search
Duplicate

setNeedsLayout와 setNeedsDisplay의 차이에 대해 설명하시오.

Created
2023/10/16 04:21
Tags
iOS
태그

 면접 질문 : setNeedsLayout와 setNeedsDisplay의 차이에 대해 설명하시오.

1. main run loop

기기에서 앱 아이콘을 터치하게 되면 @main을 찾아 UIApplication 객체와 AppDelegate 객채를 생성한다.
그리고 이내 main run loop가 실행된다. main run loop는 터치 이벤트, 위치의 변화, 디바이스의 회전 등의 각종 이벤트들을 처리하게 된다. 이러한 처리 과정은 각 이벤트들에 알맞는 핸들러를 찾아 그들에게 권한을 처리 권한을 위임하며 진행된다.
발생한 이벤트들을 모두 처리하고 권한이 다시 main run loop로 돌아오는 시점을 update cycle 이라고 한다.

update cycle

main run loop에서 이벤트가 처리되는 과정에서 버튼을 누르면 크기나 위치가 이동하는 애니메이션과 같이 layout이나 position 값을 바꾸는 핸들러가 실행될 때도 있다.
이러한 변화는 즉각적으로 반영되는 것이 아니다.
시스템은 이러한 layout이나 position이 변화되는 View를 체크한다. 그리고 모든 핸들러가 종료되고 main run loop로 권한이 다시 돌아오는 시점인 update cycle에서 이런 View들의 값을 바꿔주어 position이나 layout의 변화를 적용시킨다.
이러한 시간차가 존재하는 것을 인지해야 setNeedsLayout을 쉽게 이해할 수 있다.

2. layoutSubViews()

layoutSubviews는 UIView의 인스턴스 메서드이다.
이 메서드가 호출되면 해당 view와 subView들이 모두 연달하 호출된다. 이는 비용이 많이 들기 때문에 직접 호출하는 것은 지야해야 한다.
이 메서드는 view의 값이 재계산 되어야 하는 적절한 시점에 시스템에 의해 자동으로 호출된다.
추가로 UIViewController 내의 view가 layoutSubviews() 메서드를 호출하게 되면 값이 갱신되고 이후 UIViewController의 viewDidLayoutSubviews() 가 호출 된다. 갱신된 view의 값에 의존하는 행위들은 이 메서드 내에 명시해줘야 한다.
다음과 같은 상황에서는 시스템이 자동으로 size 혹은 position이 변경되어야 하는 view라고 체크를 하고, update cycle 에서는 layoutSubviews() 가 호출되어 체크된 view들의 변경사항을 반영한다.
view의 크기를 조절할 때
Subview를 추가할 때
사용자가 UIScrollVIew를 스크롤할 때
기기를 회전할 때
view의 autolayout constraint 값을 변경할 때
위에 나열된 시점에는 자동으로 update cycle에서 layoutSubview() 를 호출하는 행위를 예약하는 것이다.
그렇다면 수동으로 예약하려면? setNeedsLayout

3. setNeedsLayout

Invalidates the current layout of the receiver and triggers a layout update during the next update cycle

Declaration

func setNeedsLayout()
Swift
복사

Discussion

뷰의 하위 뷰들의 레이아웃을 조정하고 싶을 때 메인 스레드에서 이 메서드를 호출한다. 이 메서드는 요청을 기록하고 즉시 반환한다.
왜냐하면 이 메서드는 강제로 즉시 업데이트파지 않고, 다음 업데이트 주기를 기다리기 때문에 여러 뷰들이 업데이트 되기 전에 여러 뷰들의 레이아웃을 무효화 시킬 수 있다.
이 동작을 통해 모든 레이아웃 업데이트를 하나의 업데이트 주기로 통합할 수 있으며 일반적으로는 성능이 더 좋다.
이 메서드를 호출한 view는 재계산이 필요한 view라고 시스템에게 알려주며 이후 update cycle에서 layoutSubviews() 가 호출된다.
setNeedsLayout 메서드와 setNeedsDisplay 메서드를 비교하였지만 이름만 비슷하지 행동은 전혀 다르다.

4. setNeedsDisplay

Marks the receiver’s entire bounds rectangle as needing to be redrawn.

Declaration

func setNeedsDisplay()
Swift
복사

Discussion

이 메서드 혹은 setNeedsDisplay(_:) 를 사용하여 view의 컨텐츠를 다시 그려야한다고 시스템에게 알려줄 수 있다.
이 메서드는 요청을 기록하고 즉시 반환한다. view는 다음 드로잉 주기가 오기 전까지는 그려지지 않는다.
다시 말해 모든 view 가 없데이트 되어야 다시 그려진다.
setNeedsDisplay가 호출된 후, 다음 업데이트 주기가 되고 draw 메서드가 호출될 때 해당 뷰의 업데이트들이 한번에 이뤄진다.

Summary

setNeedsLayout() 메서드와 setNeedsDisplay() 메서드 모두 호출 즉시 실행되지 않고 다음 update cycle에 변경사항이 적용된다.
setNeedsLayout은 layoutSubview 메서드를, setNeedsDisplay는 draw 메서드를 시스템이 호출하게끔 유도한다.
setNeedsLayout() 메서드는 모든 핸들러가 종료되고 권한이 main run loop로 돌아오는 시점에 view의 position이나 layout에 관한 변화를 적용시키고,
setNeedsDisplay() 메서드는 다음 드로잉 사이클이 오면 그 때 쌓여있는 그려야할 컨텐츠들을 동시에 적용시킨다.

reference