Dev_Dylan

[iOS] Lifetime of SwiftUI (with Demystify SwiftUI_2) 본문

iOS/SwiftUI

[iOS] Lifetime of SwiftUI (with Demystify SwiftUI_2)

Dylan_21 2024. 1. 28. 17:42

WWDC21의 Demtystify SwfitUI의

- Identity

- Lifetime

- Dependencies

중 Lifetime에 대한 내용 정리

 

 

WWDC 21: Demystify SwiftUI

첫번째 포스팅:  Identity에 대한 내용

 

 

요약 및 정리

 

1.

SwiftUI는 새로운 View가 다시 호출될 때

이전 Value와 바뀔 Value와 복사하여 비교하고 비교가 끝난뒤 소멸한다.

 

2.

View Value, View Identity는 같지 않다.

View Value는 일시적이기 때문에 Lifetime에 의존하면 안된다.

 

3.

View Lifetime은 Identity의 지속 시간을 따라간다.

 

4.

Children View 의 View가 지속적으로 랜더링 되더라도,

View Value를 유지하기 위해 State, StateObject 를 사용한다.

(일종의 View의 ID와 관련된 영구 저장소)

 

5.

branch에 따라 뷰가 전환되면 View는 소멸되고 다른 View가 생성된다.

 

6.

State Lifetime은 View Lifetime과 같다.

 

7.

ForEach로 동적인 View를 생성할 때,

Range를 사용하기 보다 Identity를 가지고 있는 Data를 사용하는 것이 좋다.

 

8.

Identifiable한 프로토콜의 목적은

SwiftUI가 Lifetime동안 Data를 추적할 수 있도록

Type Stability ID를 제공하도록 하는 것이다.


Lifetime

SwiftUI의 ID가 View & Data 의 Lifetime 과 연결되는지 알아보자.

 

 

PurrDecibelView는 고양이의 그르렁거리는 소리의 강도를 나타내는 View임

아래 Line은 intensity (그르렁 거리는 소리의 강도)가

25에서 → 50으로 증가

 

동일한 View에서의 두개의 고유한 값이다.

SwiftUI는 두개의 값을 비교하기 위해 복사본을 유지함

비교후 필요가 없어지면 고유의 25 값은 사라진다.

 

 

 

여기서 중요한 부분

 

View Value는 일시적이기 때문에 Lifetime에 의존하면 안된다.

View Value는 말 그대로 View의 지금 상태의 값으로 생각하면 좋다

(물론, 랜더링 되면서 Value값이 잠시 남아있다.)

 

 

But, 우리는 ID를 통제할 수 있다.

 

View의 id가 변경되거나 View가 제거되면 LifeTime이 종료되고, 그 전까지는 하나의 view를 나타냄.

 

 

View Lifetime과 ID의 지속 시간은 항상 같이 언급되는데,

그 이유는 View의 생명이 ID의 지속 시간을 따라가기 때문이다.

 

 

 

 

하위 View는 계속 사라지고 만들어지기를 반복한다.

때문에 현재 하위 View보다 LifeTime이 긴 저장이 필요할 때가 있다.

@State, @StateObject 가 이를 해결해줌.

 

@State @StateObject는 VIew의 ID와 관련된 영구 저장소.

SwiftUI는 VIew ID가 처음 생성될 때

초기값을 사용해 State, StateObject에 대한

메모리에 저장소를 할당함.

파란색 부분 : State 변수인 Title

초록색 부분 : CatRecorder, 즉 현재 View

 

CatRecorder가 생기거나 랜더링 될 때,

title은 @state로 선언되어 CatRecorder 의 Lifetime 무시하고 계속 남아있는 것을 보여준다.

 

 

구체적으로 Deep Dive 해보자.

 

body에 2가지 Branch가 있다.

if 루프에 들어가면서 스토리지에 데이터가 올라가게 되고,

dayTime이 변경됨에 따라 View가 바뀌게 된다면

이전에 있던 데이터는 (deallocated)할당 취소되고 새 저장소가 생성된다.

즉, dayTime이 toggle 될 때 마다 View는 재생성 될것임

 

재생성 된다? -> ID 가 바뀐다.

 

 

Toggle을 통해 True일 때로 돌아가도 같은 방법으로 진행된다.

ID가 변경될 때 마다 상태가 대체된다.

 

 

View가 새로 생성되기 때문에 State도 초기화 되고

상태의 지속성은 View의 Lifetime과 연결되어있다.

 

 

 

 

Data의 ID를 View에 대한 explicit(명시적) ID의 한 형태로 사용하는 데이터 기반 구성을 예로 들어보자.

대표적으로 ForEach가 있다.

 

 

ForEach 초기화할 수 있는 방법

첫번재로 가장 간단한 방법은 일정 범위의 사용이다.

아래와 같이 Range로 명시해주는 것이다.

이는 프로토타입과 같이 임시로 구현하는데 주로 사용한다.

 

 

 

ForEach가 아래와 같이 구현되고,

 

이렇게 각각에 View가 살아있는 동안 ID가 안정적으로 보장된다.

 

 

 

 

 

위와 같이 sheeps로 동적으로 사용하는것은 오류를 유발함.

 

 

두번째로 동적으로 생성하는 방법이다.

 

모든 컬렉션 요소에서 생성된 모든 뷰에 ID를 할당하기 때문에 모든 Property는 Hashable해야함

 

 

Data에 안정적으로 ID를 제공하기위해 Identifiable를 채택한다.

그렇다면 SwiftUI는 프로토콜을 치대한 활용해 keyPath를 생략하고 식별자를 사용해 View 와 데이터에 ID를 정의한다.

 

 

 

근데 ForEach가 어떻길래 Identifiable을 채택해서 안정적으로 사용할 수 있을까?..

 

ForEach DeepDive 해보자!

 

여기서 Data를 사용한다면 Data는 Identifiable하도록 제한되어있음.

 

 Identifiable한 프로토콜의 목적은 SwiftUI가 Lifetime동안 Data를 추적할 수 있도록 Type Stability ID를 제공하도록 하는 것.!!!

 

 

정리하면

  • View Values 는 일시적이기 때문에 Lifetime에 의존하면 안된다
  • View Lifetime 은 지속적이기 때문에 연속성을 제공함
  • Views의 ID를 제어할 수 있음, ID를 사용해 State Lifetime 범위를 명확하게 지정 가능함.

 

'iOS > SwiftUI' 카테고리의 다른 글

[iOS] Identity of SwiftUI (with Demystify SwiftUI_1)  (2) 2024.01.27
Comments