[WWDC2021] Demystify SwiftUI

Valse·2022년 12월 14일
2

WWDCMemos

목록 보기
2/2

SwiftUI의 선언형 UI


  • 뷰를 그리면서, 어떤 목적을 달성하고자 하는지 설명하면 프레임워크가 해결해 줄 수 있다.
  • 그런데 어떤 일이 일어나고 있나?

Identity, lifetime, Dependenceis


  • 뷰가 어떤 이유로 어떻게 그려지는지, 얼마나 데이터를 갖고 뷰가 유지되어야 하는지, 그리고 그 뷰의 id는 무엇인지를 기준으로 알아보고자 한다.

Identity

  • 두 강아지가.. 다르다면? 어떻게 다른가? 그 동일성은 어디서 오는가?
  • SwiftUI가 동일성을 통해 뷰를 구분하기 때문에 이 물음은 중요하다. 어떻게 동일성을 갖게 할 것인가?
  • 두 뷰의 컴포넌트가 다르다고 가정하다면, fade in-out으로 그릴 수 있고, 같다면 trasition으로 뷰가 옮겨다닐 수 있음을 의미한다.
  • ID를 갖고 명시적인 identity를 가질지, 아니면 구조에 따른 identity를 가질지는 차이가 있을 수 있다.
  • 메모리 주소로 id를 갖게 하는 pointer ID 방식은 SwiftUi가 선호하지 않는다.
  • 구조체로서의 뷰는 값 타입으로서 작용하기 때문에 모든 뷰는 copy 된다는 점도 한몫하고, .id 수식어로 id를 명시적으로 줄 수 있다.
  • 반면 구조적 identity는 어떠한가?
  • 조건문에 따라 서로 다른 뷰가 나뉠 때, true View, false View라는 구별이 가능하다.
    - 뷰의 제네릭 타입을 보기 때문에 이러한 구별은 강하게 보장된다.
    • SwiftUI는 더 유연한 변화를 지향하기 때문에 구조적 Identity 구별을 더욱 장려한다.

AnyView(type easing wrapper type)

  • 그런데 만약 AnyView를 쓰면 어떻게 될까?
  • 구조적 동일성이 AnyView라는 제너릭 타입으로 단일화되기 때문에 리턴되는 제너릭 타입에 대응하는 some View가 서로 다른 뷰로 구별되지 않는다.
  • 보자마자 굉장히 이해하기 어려운 코드가 되는 동시에, 동일성을 해치고 퍼포먼스도 낮추기 때문에 AnyView의 사용은 지양하는 것이 좋다.
  • AnyView를 쓰기보다는 if, 삼항연산, switch 등으로 대치하여 쓰도록 하자.

Lifetime

  • 언제까지 뷰는 살아있는가? 동일성을 가진 뷰가 시간에 의해 데이터에 남아있는 것을 수명이라 한다.
  • 같은 뷰에서 State의 변화로 인해 뷰가 새로 그려진다면, 이전 값을 갖고 있던 뷰는 사라진다.
  • View ValueView Identity는 서로 다르다.
  • 뷰의 수명은 화면에서 보이는지의 여부에 따라 결정된다(onAppear ~ onDisappear)
  • 뷰의 id에 연관되는 내부의 State와 StateObject는 그 값이 바뀔 때마다 뷰를 새로 그린다.
  • 서로 다른 동일성을 갖는 뷰가 조건에 의해 분기처리 된다면, 조건에 의해 뷰가 바뀔 때마다 뷰의 데이터는 말소되고 새로 초기화된다.
  • 따라서 State의 수명은 View의 수명과 동일하게 유지된다.
  • 동일성을 유지해야 각 뷰가 갖는 State가 안정적임을 보장할 수 있기 때문에, List, ForEach에 다이나믹한 콜렉션을 돌리고 싶다면 Identifiable, Hashable 프로토콜을 넣어주도록 하자(애초에 정의할 때부터 Content 제너릭 타입이 Identifiable을 채택할 것을 요구하긴 하지만).
  • 뷰 빌더는 모두 Data Driven 하다는 점을 함께 기억하자.
  • 뷰의 수명은 그것의 id가 유지되는 기간을 의미하며, state의 일관성은 수명에 종속된다.

Dependency

  • 의존성은 뷰의 input 에 불과하다.
  • SwiftUI의 뷰 컴포넌트가 갖는 action들은 뷰의 의존성을 변경시키는 행동을 할 수 있고, 이는 뷰를 다시 계산하도록 한다.
  • 뷰의 계층에 따라 뷰에 어떤 데이터가 종속되어서 변화를 촉구하는지 달라질 수 있다.
  • 사진의 맨 아래의 state는 자신의 변화에 따라 2개의 뷰를 바꾸도록 한다.
  • 그런데 만약 이 변화된 뷰의 하위 뷰가 수명주기에서 내려가 있다면 굳이 그 뷰가 다시 그려지지는 않을 것이다.

Identifier Stability & Uniqueness

  • 수명에 직결되며 성능 향상에 도움이 될 수 있다.
  • minimizes dependency churn
  • UUID().uuidstring 같은 random generated id는 뷰에 의해 생성될 때마다 바뀌기 때문에 stable하지 않다.
  • id는 따라서 유니크해야 하는데 이 역시 성능 향상과 직관적 애니메이션에 도움을 준다.
  • 그런데 구조적 동일성에 의해 if 조건에 따라 브랜치가 나뉠 수 있다. 이러면 동일한 id를 가진 2개의 뷰가 생길 수 있고 애니메이션을 저하하거나 state의 안정성을 해칠 수 있다. 이럴 땐 삼항연산자(Dependent Code)를 써보자.
profile
🦶🏻🦉(발새 아님)

0개의 댓글