UI 는 Main Thread 에서 갱신을 관리한다. UI 갱신이 한 업데이트 사이클에 우선적으로 이루어져야 할 경우 GCD 의 DispatchQueue.main.async {} 를 사용할 수 있다. 아래는 viewDidLoad, viewWillAppear 등과 같은 일반적으로 사용하는 UIView 의 메소드들 외에 좀 더 내부적으로 디테일한 방식의 메소드들을 설명해놓았다.
기본적으로는 Main Run Loop (위에 언급한 GCD Main Thread) 에서 UI 의 갱신을 담당한다.
이곳에 무거운 연산로직을 넣을 경우 화면이 멈출 수 있다.
DispatchQueue.main.async { 이곳에 무거운 연산로직을 넣지 말라. } 화면 갱신이 먼저 수행되어야 할 것을 넣어주어야 한다.
이벤트 큐가 있어서 아래와 같은 이벤트가 발생시
- 리사이징 뷰,
- 서브뷰 추가,
- UIScrollView 에서 스크롤시 UIScrollView 와 그것의 superview,
- 화면 회전,
- 뷰의 constraints (제약조건)
가 바뀌는 이벤트들이 발생할 경우 layoutSubviews 가 호출되어 화면 갱신을 한다.
하지만 Label 의 text 를 수정할 경우 자동 반영이 되지 않으므로 위와 같은 이벤트가 발생되거나
DispatchQueue.main.async {} 에 text 수정하는 것을 넣어주거나
setNeedsLayout 을 호출하거나 해야한다.
layoutSubviews 는 일반적인 UI 갱신 시 호출되는 메소드이다. 하위 UIView 들과의 위치와 제약조건등을 함께 갱신한다. override 해서 사용하는 생명주기 함수같은 방식이다.
setNeedsLayout 는 호출시 다음 업데이트 사이클에서 반드시 갱신을 수행한다. 급하게 갱신이 필요할 경우 호출을 하는 메소드이다. 하위 뷰 그리고 위치, 제약조건 등을 모두 포함하여 갱신한다. 즉, 이것을 호출하면 다음 업데이트 사이클에서 layoutSubviews 가 수행된다고 볼 수 있다.
layoutIfNeeded 는 해당 사이클에서 해당 뷰 부분만 강제로 바로 즉시 갱신을 해줄 때 사용한다. 하위뷰는 아니고 해당하는 뷰만을 강제로 갱신한다. 애니메이션 같은 것을 구현할 때 동작이 끝나고 초기화 시킬 때라던가 이런 경우 이것을 사용한다.
Method purposes | Layout | Display | Constraints |
Implement updates (override, don’t call explicitly) | layoutSubviews | draw | updateConstraints |
Explicitly mark view as needing update on next update cycle | setNeedsLayout | setNeedsDisplay | setNeedsUpdateConstraints invalidateIntrinsicContentSize |
Update immediately if view is marked as “dirty” | layoutIfNeeded | updateConstraintsIfNeeded | |
Actions that implicitly cause views to be updated | addSubview Resizing a view setFrame that changes a view’s bounds (not just a translation) User scrolls a UIScrollView User rotates device |
Changes in a view’s bounds | Activate/deactivate constraints Change constraint’s value or priority Remove view from view hierarchy |
https://tech.gc.com/demystifying-ios-layout/
UI 의 메인 쓰레드의 동작 원리를 정확히 이해하고 Thread 기반으로 개발할 경우 적절히 UI 업데이트 시점을 고려하여 개발을 해주어야 한다.
'MAC & iOS' 카테고리의 다른 글
Swift 문법 (0) | 2022.01.16 |
---|---|
swift 창시자 구글 브레인팀 합류 (0) | 2021.10.17 |
iOS 개발을 하며 React 의 함수형개발방식이 그냥 옵션일 뿐임을 상기시켜주었다. (0) | 2021.09.08 |
cocoapods 업데이트 repo 변경사항. Git MasterSource 에서 CDN TrunkSource 로 (1) | 2021.04.20 |
My Mac initial setting (0) | 2018.07.13 |