TAGS
주제로 글을 찾습니다
Tech, Domain, Journal 글에 붙은 공통 태그를 모았습니다.
Data Essentials in SwiftUI (WWDC20 10040)
Curt Clifton·Luca Bernardi·Raj Ramamurthy가 SwiftUI의 데이터 소유권·source of truth·@State/@StateObject/@ObservedObject·view life cycle을 한 번에 정리한 세션. 내용·코드·맥락을 한국어로 재구성한다.
Demystify SwiftUI (WWDC21 10022)
Matt Ricketson·Luca Bernardi·Raj Ramamurthy의 대표 세션. identity·lifetime·dependencies 세 축으로 SwiftUI의 업데이트 규범을 체계화한다. dependency graph가 곧 SwiftUI의 render tree라는 것까지.
Demystify SwiftUI Performance (WWDC23 10160)
SwiftUI 앱이 느려지는 원인을 진단하는 법. printChanges로 의존성 추적, body 안의 work 제거, List/Table의 identity 수집 메커니즘까지 — 2021 Demystify가 이론이라면 이 세션은 최적화 매뉴얼이다.
SwiftUI의 Identity · Lifetime · Dependencies
Omar Radwan의 SwiftUI Under the Hood 번역. Demystify SwiftUI 세션(WWDC21 #10022 · WWDC23 #10160)의 세 기둥인 identity·lifetime·dependencies를 코드 예제와 함께 정리한다.
Discover Observation in SwiftUI (WWDC23 10149)
Swift 5.9의 @Observable 매크로는 ObservableObject의 구조적 한계를 뒤집는다. body가 실제로 읽은 property만 추적하는 granular tracking 메커니즘과, @State·@Environment·@Bindable 세 개로 단순화된 property wrapper까지.
A Day in the Life of a SwiftUI View
SwiftUI의 view tree → render tree 변환, .task 재실행 문제와 .id/.task(id:)의 트레이드오프, proposal-reporting 레이아웃 시스템, environment와 preferences의 방향성을 그림 100여 장으로 풀어낸 Chris Eidhof의 강연 정리.
Variadic Views in SwiftUI
VStack 안에 여러 뷰를 넣으면 SwiftUI는 그걸 어떻게 들고 있을까. TupleView·_VariadicView.Tree·UnaryViewRoot/MultiViewRoot의 구분, 그리고 List가 행 사이에 Divider를 끼워 넣을 수 있는 이유까지.
SwiftUI의 내부 동작 원리
View tree, Attribute Graph, _UIHostingView까지 — SwiftUI가 선언형 뷰를 실제 UIKit·Core Animation 위에 매핑하는 내부 구조를 따라간다.
TCA Under the Hood
TCA(The Composable Architecture)를 쓰면서 "왜 이렇게 동작하지?" 싶었던 순간들이 있었다. send가 동기인 것 같으면서도 Effect가 비동기고, 같은 액션을 두 번 보내면 경고가 뜨고, scope를 호출할 때마다 새 Store가 생기지 않는 것처럼 느껴지고.
AttributeGraph 풀어 보기
Apple 이 숨겨 놓은 AttributeGraph 프레임워크를 lldb 로 직접 찔러 본 기록. AG::Graph::print() 심볼을 GraphViz 로 덤프해 state 변경 → dirty 전파 → lazy evaluation → RootDisplayList 갱신까지 실제 그래프로 확인한다. subgraph 가 view tree 의 동적 구조를 어떻게 포장하는지까지.
State·Action·Reducer·Store와 단방향 흐름
SwiftUI로 화면 몇 개를 만들어 보면 상태 관리가 곧 벽이 된다. 작은 뷰는 @State로 충분하지만, 화면이 커지면 여러 뷰가 같은 값을 공유해야 하고 @ObservedObject, @EnvironmentObject가 섞여 들어온다. 문제는 값을 바꾸는 경로가 정해져 있지 않다는 데 있다. 어떤 버튼이 어디의 상태를 직접 고치고, 그 변화가 또 다른 상태를 건드리기 시작하면 "지금 이 값이 왜 이렇게 됐는지"를 되…
실전 구성 팁
기본기를 익히고 실제 화면을 만들기 시작하면 곧 다른 종류의 어려움을 만난다. 문법이 아니라 구조의 문제다. body 안에 뷰가 쌓이면서 수십, 수백 줄이 되고, 어디를 고쳐야 할지 눈에 안 들어온다. 조건 분기와 스택이 겹치면 들여쓰기만 깊어진다.
SwiftUI 의 diffing algorithm
SwiftUI 가 React 처럼 identifier 나 shortest-edit-script 없이도 대부분의 경우 view 변화를 모호함 없이 판별하는 이유. 비결은 정적 타입. TupleView<(Text, _ConditionalView<A, B>)> 자체가 구조를 드러내므로 같은 타입끼리만 비교하면 된다. Swift 코드로 직접 재구성해 본다.
상태로 화면을 제어한다
UIKit에서 얼럿을 띄우려면 present(alert, animated: true)를 호출했다. 화면 전환도, 액션 시트도 전부 "지금 띄워라"라고 명령하는 함수 호출이었다. SwiftUI로 넘어와 처음 얼럿을 띄우려 할 때 이 함수를 찾다가 막힌다. 그런 함수가 없기 때문이다.
SwiftUI 의 render loop
body 평가와 실제 화면 렌더링은 같지 않다. onAppear 가 왜 깜빡임을 만들지 않는지, preference key 기반 커스텀 layout 에서 body 가 두 번 평가돼도 왜 첫 번째는 화면에 닿지 않는지 — CFRunLoop 의 beforeWaiting observer 와 암묵적 CATransaction 의 관계까지 내려가 설명한다.
데이터 흐름의 두 원칙
선언형 감각을 잡고 나면 곧바로 막히는 지점이 있다. 상태를 담는 방법이 하나가 아니라는 것이다. @State, @Binding, @ObservedObject, @StateObject, @EnvironmentObject가 줄줄이 나오는데, 처음에는 무엇을 언제 써야 하는지 감이 안 온다. 아무거나 골라 쓰다가 화면이 갱신되지 않거나, 반대로 값이 자꾸 초기화되는 문제를 겪는다.
SwiftUI 에서 escaping closure 를 쓰지 말아야 하는 이유
커스텀 container view 를 만들 때 content 를 @escaping closure 로 받을지, 초기화 때 바로 평가해서 view 로 저장할지. 겉보기엔 closure 쪽이 더 효율적이지만 실제로는 @State 최적화와 memoization 이 동시에 깨진다. Rens Breur 가 왜 view 는 이미 함수인지부터 짚고 시작한다.
명령형에서 선언형으로
UIKit을 쓰다 SwiftUI로 넘어오면 가장 먼저 찾게 되는 것이 "화면을 다시 그리는 함수"다. UIKit에서는 그게 일이었기 때문이다. 카운트가 하나 늘면 countLabel.text를 새로 대입하고, 버튼을 잠가야 하면 button.isEnabled = false를 부른다. 데이터가 바뀔 때마다 그 변화를 화면에 반영하는 코드를 사람이 직접 써 준다. 이게 명령형 방식이다.