Demystify SwiftUI - Dependency
종속성(Dependency)은 SwiftUI가 언제, 그리고 왜 UI를 업데이트해야 하는지 이해하는 방식입니다. 이는 앱의 성능과 정확성에 직결됩니다.
종속성이란 뷰의 입력값(input)으로, 종속성이 변경되면 뷰는 새로운 body를 생성합니다. 여기서 입력값은 @State, @Binding, 프로퍼티 등이 있고, 이 값들이 변경되면 뷰는 다시 그려집니다.
body는 뷰의 계층 구조를 만드는 곳이고, 이 뷰의 게층 구조를 더 깊이 보면, 액션(action)이 있는 버튼이 있습니다. 액션은 뷰의 종속성에 변경을 일으킵니다. SwiftUI의 뷰 계층은 단순한 트리 구조가 아니라 ‘그래프’ 구조입니다. 왜냐하면 여러 뷰가 하나의 동일한 데이터 소스에 의존할 수 있기 때문입니다. 그래프 구조 덕분에 데이터가 변경되면, SwiftUI는 그래프를 따라 오직 그 데이터에 의존하는 뷰들만 찾아내어 효율적으로 업데이트합니다.
위의 코드와 그래프를 보면 알 수 있지만, 뷰들은 데이터에 의존하고 있고, 동일한 데이터에 대해 여러 뷰가 의존하고 있을 수 있습니다.
Identity
따라서 정확하고 효율적인 종속성 그래프를 만드려면 좋은 Identity를 만드는 것이 필수적입니다. Identity를 통해 꼭 필요한 뷰만 데이터가 의존하도록 하여 UI를 효율적으로 업데이트 할 수 있습니다.
좋은 Identity는 다음과 같습니다.
Explicit Identity은 안정적(stability)이고 고유(uniqueness)해야 합니다.
- 안정성(stability): ID는 시간이 지나도 변하지 않아야 합니다.
- 좋은 예: 데이터베이스의 고유 ID처럼 영구적이고 변하지 않는 값
- 나쁜 예: 매번 새로 생성되는 랜덤 UUID, 데이터의 순서가 바뀌면 달라지는 배열의 인덱스
- 고유성(uniqueness): ID는 컬렉션 내에서 중복되지 않아야 합니다.
- 좋은 예: 각 상품의 고유한 ‘시리얼 번호’
- 나쁜 예: 여러 개일 수 있는 상품의 이름
Structural Identity는 불필요한 분기를 피해야 합니다.
- 뷰의 상태를 표현하기 위해 if-else문과 같은 분기처리를 사용하여 뷰 전체를 교체하지 않는 것을 권장합니다. 이는 불필요하게 Identity를 분리하여 성능 저하와 상태 유실을 유발합니다. 대신 Modifier를 통해 Identity는 유지하면서 상태를 변경할 수 있습니다. 예를 들어 .opacity(isExpired ? 0.5 : 1.0) 처럼 수식어 내부에서 조건을 처리하면, 뷰의 Identity는 하나로 유지하면서 모습을 바꿀 수 있기 때문에 훨씬 효율적이고 안전합니다.
결론 및 핵심정리
위 내용을 정리하자면 Dependency를 기반으로 뷰가 그려지는데, 불필요한 재생성 등을 막고 효율적으로 관리하기 위해 Identity를 잘 설정하는 것이 중요합니다. Identity가 중요한 이유는 Identity가 뷰의 수명(Lifetime)을 결정하고, 이 수명이 다시 뷰의 상태 저장소의 생명 주기를 결정하기 때문입니다.
- 불안정한 명시적 정체성(Unstable Explicit Identity)의 진짜 문제: ForEach에서 불안정한 ID(예: 랜덤 UUID)를 사용하면, SwiftUI는 단순히 UI를 비효율적으로 업데이트하는 것을 넘어 모든 항목을 완전히 새로운 뷰로 인식합니다. 그 결과, 이전 뷰들의 수명이 끝나고 그 뷰들이 가지고 있던 모든 @State가 파괴됩니다. 리스트의 각 항목이 자체적인 상태(예: 선택 여부 토글)를 가지고 있었다면 그 상태가 모두 초기화되는 것입니다.
- 불필요한 구조적 분기(Unnecessary Structural Branch)의 진짜 문제: if-else 문으로 뷰를 교체하면, 화면 전환이 부자연스러운 것뿐만 아니라 if 블록의 뷰와 else 블록의 뷰가 서로 다른 정체성을 갖게 됩니다. 분기가 전환되는 순간 이전 뷰의 수명이 끝나고, 그 뷰가 가진 @State 저장소는 메모리에서 완전히 해제됩니다. 사용자가 입력한 내용이나 스크롤 위치 같은 상태가 사라지는 이유가 바로 이것입니다.
결론적으로, SwiftUI에서 정체성(Identity)을 올바르게 설계하는 것은 UI 업데이트 효율을 넘어 앱의 정확성과 직결됩니다. 좋은 정체성은 예측 가능한 수명(Lifetime)을 보장하고, 이 수명은 뷰의 상태(@State)를 안전하게 보존하는 기반이 됩니다. 이렇게 안정적으로 유지되는 뷰와 상태가 모여 비로소 정확하고 효율적인 종속성(Dependency) 그래프가 완성되는 것입니다. 따라서 좋은 정체성은 SwiftUI 앱의 성능과 안정성 모두를 잡는 핵심 열쇠라고 할 수 있습니다.
'iOS > SwiftUI' 카테고리의 다른 글
[SwiftUI] WWDC2021 - Demystify SwiftUI - Lifetime (0) | 2025.09.07 |
---|---|
[SwiftUI] Source of Truth (0) | 2025.08.30 |
[SwiftUI] WWDC2021 - Demystify SwiftUI - Identity (0) | 2025.07.26 |
[SwiftUI] View Protocol과 ViewBuilder (0) | 2025.04.17 |
[SwiftUI] SwiftUI란 (0) | 2025.04.17 |