티스토리 뷰

🍏/SwiftUI + Combine

[SwiftUI] task modifier

eungding 2023. 3. 8. 21:31
반응형

[1] task modifier

task(priority:_:)   // Adds an asynchronous task to perform before this view appears.

-  task(id:priority:_:)  // Adds a task to perform before this view appears or when a specified value changes.

 

 

[2] 필요성

task modifier 가 나오기 전에는 

뷰가 disappear 될 때  진행 중인 task 를 cancel 해주기 위해

어딘가에 (아래 예제는 뷰인데 보통 뷰모델)  task 를 들고 있고 onDisappear 에서 cancel을 해줘야했음. 

struct SampleView: View {
    
    var body: some View {
        ... 
        .onAppear {
            fetchImageTask = Task {
                await viewModel.fetchImage()
            }
        }
        .onDisappear {
            fetchImageTask?.cancel()
        }
    }
}

 

하지만 task modifier를 쓰면

위의 onAppear, onDisappear 세트 & task reference 를 모두 대체 가능. 

struct SampleView: View {

    var body: some View {
        ... 
        .task {
            await viewModel.fetchImage()
        }
    }
}

 

SwiftUI가 자동으로

뷰가 appear 될 때 (정확히는 before view appear) Task 를 실행시키고

뷰가 disappear 될 때 (정확히는 after view disappear) Task 를 cancel 시켜주기 때문. 

SwiftUI will automatically cancel the task at some point after the view disappears before the action completes.

 

 

[3] Task.checkCancellation()

 

하지만 요 영상의 마지막 쯤을 보면 

Nick 선생님의 개인앱에서 for 문으로 여러 task 를 돌리는 코드가 있는데,

뷰가 disappear 될 때 task modifier 가

모든 task 들을 cancel 시키지 않았다고 함..

 

Task Cancellation에 이런 내용이 있다고 한다. 

In a long-task that includes multiple pieces, you might need to check for cancellation at several points, 
and handle cancellation differently at each point. 

 

해당코드를 보여주지 않으셨으나 비슷하게 for문을 돌려봤는데

나는 재현이 안되었음. (버그인데 픽스된 걸 수도..? )

 

아무튼 이럴 때 for 문 안에 checkCancellation() 을 사용하면 된다. 

task가 이미 cancel 되었으면 에러를 던지는 Type Method 로,  이걸 사용하면 더 이상 task 가 진행되지 않게 할 수 있다. 

 

 

 

 

 

 

반응형
댓글