먼저 뷰모델을 만들어주고 data가될 Array도 구성해줬다
그리고 fetch메소드와, data들이 download되고 있다는 가정하에
download메소드도 작성해줌
뷰는 스크롤뷰로 구성해주고, ForEach뷰도 함께 작성해서 dataArray를 띄워줄 예정
이 상태에서 앱을 실행하고 디버그 네비게이터에서 CPU를 확인해보면
요렇다!
그리고 로드데이터를 터치해보면 스파크처럼 물결이 하나 생김
fetchData의 메소드를 백그라운드 스레드로 바꿔보자
실행하게되면 보라색에러가 발생하는 걸 볼 수 있음
ui를 업데이트 하는 스레드는 메인에서 동작해야하기 때문!!
이렇게 수정해주자
그리고 global 스레드 내에서 qos,
quality of service를 설정이 가능함
.background로 선택해주고
기존의 VStack을 LazyVStack으로 바꿔보자
Thread를 확인해보면 global 큐는 메인 Thread가 아니고
main.async는 메인스레드인걸 볼 수 있음
ARC에 대해서 먼저 알아야함 (자동참조카운팅임)
간단한 형태의 네비게이션뷰를 만들었다
뷰모델을 만들어주고 init될 때와 deinit되는 순간을 추적해볼 예정
secondScreen에서 뷰모델의 인스턴스를 생성하고
vm.data가 nil이 아닐경우에 텍스트뷰를 표현하게 해줬음
시뮬레이터 실행해보자
처음 NavigationLink를 터치해서 SecondView로 들어갔을 땐
InitializeNow 프린트만 출력됨
뒤로 갔다가 다시 SecondView로 들어가는 시점부턴 DeInitialize Now도 출력되는 걸 볼 수 있음
🤔 왜 처음은 deinit이 안 나오는 걸까?
StateObject로 하나가 잡혀있게 되는거 같음
@AppStorage를 사용해서 추적해보자
첫번째 뷰에서 overlay로 텍스트 뷰를 만들어주고, 텍스트의 내용은 count로 작성해줌
그리고 뷰모델이 init될 때 UserDefaults 에 저장된 count값을 +1 해주고,
deinit될 땐 -1 해줬음
첫번째 뷰가 init 될 때 count = 0이 되게 해주고
빌드해서 실행해보면
스크린을 왔다갔다 했을 때 1이 계속 유지된다
지금같은 경우가 만약에 비동기 작업이었다면 문제가 발생함
getData가 background 큐에서 작업이 실행된다고 가정해보자
clousre구문 내에 있으니까 data 앞에는 self가 붙어야 함
근데 이 작업에서 data를 가져오는 과정이 많은 양의 정보들을 가져온다고 쳐보자
유저가 앱을 사용하는 동안 백그라운드에서 계속 작업이 진행중일 거임
근데 유저가 떠나거나 더이상 앱을 사용하지 않을 때도 이 작업이 남게 됨
asyncAfter로 500초 뒤에 실행된다고 만들어줌
빌드해서 확인해보면
뷰를 왔다갔다 했을 때 deinit은 호출되지도 않고 count는 계속 늘어나게됨 !!
self로 붙여줬던 키워드가 Strong reference가 되서 뷰모델이 할당해제 되지 못하도록 붙잡게 되버리는 겨
그리고 count갯수만큼 뷰모델 클래스도 살아있게됨
해결방법은 [weak self] in 을 붙여주면 된다!!