-
Notifications
You must be signed in to change notification settings - Fork 3
[정주] SwiftUI 구조체와 View 생성과 해제 테스트
유정주 JeongJu Yu edited this page Jul 20, 2024
·
1 revision
- WWDC를 보며 구조체와 View의 생명주기 다름을 학습함
- 구조체는 Body를 생성한 후 메모리에서 즉시 해제된다고 이해함
- 만약 구조체가 즉시 해제된다면 Body의 변화는 어떻게 감지하는지 궁금증이 생김
- 스터디원과 여러 토의를 거친 결과, WWDC의 문장 그대로 "즉시" 해제되는 것은 아니라고 판단함
- 구조체의
deinit
은 존재하지 않으므로, Class 프로퍼티를 이용한 편법을 통해 구조체 해제 시점을 확인해 봄
-
ContentView
,AView
의 각 count 프로퍼티는 SOT 변경을 통한 Body 업데이트 목적으로 정의함 -
DummyClass
를 일반 프로퍼티로 정의한 이유- 구조체가 해제될 때 함께
deinit
시키기 위해 일반 프로퍼티로 정의함 - SOT로 정의한다면 구조체가 해제되도 데이터가 유지되서 원하는 시나리오 테스트가 불가
- 구조체가 해제될 때 함께
- 해당 테스트 코드는 시뮬레이터에서 실행함
import SwiftUI
final class DummyClass {
let id = String(Array(UUID().uuidString)[..<6])
init() {
print("DummyClass init: \(id)")
}
deinit {
print("DummyClass deinit: \(id)")
}
}
struct ContentView: View {
@State var count = 0
init() {
print("Content Init")
}
var body: some View {
let _ = print("Content Body")
AView()
Button(
action: {
let _ = print("Click Content Button")
count += 1
}, label: {
Text("Content Button: \(count)")
}
)
}
}
struct AView: View {
@State var count = 0
private let dummyClass = DummyClass()
init() {
print("A Init: \(dummyClass.id)")
}
var body: some View {
let _ = print("A Body: \(dummyClass.id)")
Button(
action: {
let _ = print("Click A Button")
count += 1
}, label: {
Text("A Button: \(count)")
}
)
}
}
Content Init
Content Body
DummyClass init: CEB848
A Init: CEB848
A Body: CEB848
Click Content Button
Content Body
DummyClass init: 25A2EC
A Init: 25A2EC
A Body: 25A2EC
DummyClass deinit: CEB848
-
Content
의body
가 업데이트됨 -
A
의init
이 호출됨 -
A
의init
,body
가 호출된 뒤 이전 dummy class가deinit
됨
Click A Button
A Body: 25A2EC
Click A Button
A Body: 25A2EC
-
A
의 Button 액션은 미리 등록되었기 때문에A
의 변경만 보면 됨 ->Content
의body
는 호출되지 않음 -
A
의 SOT가 변경되었으므로A
의body
만 호출됨 -
A
의init
이 호출되지 않았으므로 dummy class의 id가 동일함
Click Content Button
Content Body
DummyClass init: 582BA7
A Init: 582BA7
A Body: 582BA7
- 기존
A
의 dummy classdeinit
이 호출되지 않음 - 새로운
A
의init
,body
호출됨 - 기존
A
의 구조체는 살아있음
- 메모리에 A 구조체가 두 개 잡혀있음
DummyClass deinit: 25A2EC
Click A Button
A Body: 582BA7
- 기존
A
의 dummy class가deinit
됨 - 그다음
A
Button의 액션이 호출됨 -
A
의body
가 호출됨
- SwiftUI의 View 구조체는 Body를 그리는 즉시 해제되지 않음 (3번 테스트)
- Body를 새로 그리기 전까지 기존 View의 구조체를 유지함. (4번 테스트)
- 3번 테스트에서 기존
A
구조체가 해제되지 않은 채 새로운A
구조체가 생성된 이유는 무엇일까- 가설1)
View
마다 구조체를 따로 관리한다. (e.g.ContentView
와AView
가 별개의AView
구조체를 관리한다.)-
Content
Button을 눌렀을 때25A2EC
가 최초 생성됨 ->ContentView
에AView
구조체(25A2EC)가 추가된다. -
A
Button을 눌렀을 때AView
의 구조체 관리에25A2EC
가 추가된다. -
Content
Button을 눌렀을 때 새로운A
구조체를 생성,25A2EC
관리는 제거된다. -
A
Button을 눌렀을 때AView
가 관리하는AView
구조체가25A2EC
에서582BA7
로 변경됨. 따라서25A2EC
를 관리하는 View가 하나도 없으므로25A2EC
는deinit
됨
-
- 가설1)
고병학 | 권승용 | 김대황 | 김인환 | 유정주 | 윤동주 | 이준복 | 이창준 | 정종인 | 홍승현 |
---|---|---|---|---|---|---|---|---|---|
bengHak | ericKwon95 | qwerty3345 | loinsir | jeongju9216 | yoondj98 | junbok97 | SwiftyJunnos | chongin12 | WhiteHyun |