새소식

iOS/SwiftUI

[SwiftUI] async / await keywords in Swift

  • -

[참고 영상]

https://youtu.be/-5kIzkBqAzc

 

[학습 목표]

Thread를 이용한 간단한 예제를 통해 async / await의 구현에 대해 알아보자.

[구현 방법]

<main을 이용한 thread 파악.>

func addTitle1(){
        DispatchQueue.main.asyncAfter(deadline: .now()+2){
            self.dataArray.append("Title1 : \(Thread.current)")
        }
    }

실행이 되면 deadline인 2초 뒤에 실행이 되는 함수.

 

<global과 main을 이용한 Thread 파악.>

func addTitle2(){
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
            let title = "Title2 : \(Thread.current)"
            DispatchQueue.main.async {
                self.dataArray.append(title)
            }
            let title3 = "Title3 : \(Thread.current)"
            self.dataArray.append(title3)
        }
    }

global : main이 아닌 다른 모든 쓰레드

global 안에 main을 실행시켜 볼 때 thread가 메인이 아닌것을 확인할 수가 있다.

viewModel.addTitle1()
viewModel.addTitle2()

을 메인에서 실행시켜 볼때 기존에 사용했던 Title1이 아닌 main thread에 넣은 Title3이 실행되는 것을 볼 수가 있다.

 

 

<await을 활용한 thread 파악>

func addAuthor1() async {
        let author1 = "Author1 : \(Thread.current)"
        self.dataArray.append(author1)
        
        try? await Task.sleep(nanoseconds: 2_000_000_000) //doSomething()
        
        let author2 = "Author2 : \(Thread.current)"
        await MainActor.run(body: {
            self.dataArray.append(author2)
            
            let author3 = "Author3 : \(Thread.current)"
            self.dataArray.append(author3)
        })
    }

author2의 경우에는 main에서 실행이 안되고 author1이나 author3의 경우에는 main으로 실행되는 것을 파악할 수가 있다.

<실행 모습>

<await을 활용한 thread 파악2>

func addsomething() async {
        try? await Task.sleep(nanoseconds: 2_000_000_000)
        
        let something1 = "something1 : \(Thread.current)"
        await MainActor.run(body: {
            self.dataArray.append(something1)
            
            let something2 = "something2 : \(Thread.current)"
            self.dataArray.append(something2)
        })
    }

위의 코드와 비슷하게 첫번째 something은 main thread가 아니고 두번째는 main thread로 실행되는 것을 볼 수가 있다.

 

<실행 모습>

[코드]

import SwiftUI
import Combine

class AsyncAwaitBootcampViewModel: ObservableObject{
    @Published var dataArray: [String] = []
    
    func addTitle1(){
        DispatchQueue.main.asyncAfter(deadline: .now()+2){
            self.dataArray.append("Title1 : \(Thread.current)")
        }
    }
    
    func addTitle2(){
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
            
            let title = "Title2 : \(Thread.current)"
            DispatchQueue.main.async {
                self.dataArray.append(title)
            }
            let title3 = "Title3 : \(Thread.current)"
            self.dataArray.append(title3)
        }
    }
    
    func addAuthor1() async {
        let author1 = "Author1 : \(Thread.current)"
        self.dataArray.append(author1)
        
        try? await Task.sleep(nanoseconds: 2_000_000_000) //doSomething()
        
        let author2 = "Author2 : \(Thread.current)"
        await MainActor.run(body: {
            self.dataArray.append(author2)
            
            let author3 = "Author3 : \(Thread.current)"
            self.dataArray.append(author3)
        })
    }
    
    func addsomething() async {
        try? await Task.sleep(nanoseconds: 2_000_000_000)
        
        let something1 = "something1 : \(Thread.current)"
        await MainActor.run(body: {
            self.dataArray.append(something1)
            
            let something2 = "something2 : \(Thread.current)"
            self.dataArray.append(something2)
        })
    }
}

struct AsyncAwaitBootcamp: View {
    
//    @StateObject private var viewModel = SubscriberViewModel()
    @StateObject private var viewModel = AsyncAwaitBootcampViewModel()
    
    
    var body: some View {
        
        List{
            ForEach(viewModel.dataArray, id: \.self) {data in
                Text(data)
            }
        }
        .onAppear{
            Task{
                await viewModel.addAuthor1()
                await viewModel.addsomething()

                let finalText = "Final Text : \(Thread.current)"
                viewModel.dataArray.append(finalText)
            }
//
//            viewModel.addTitle1()
//            viewModel.addTitle2()
            
        }
    }
}

struct AsyncAwaitBootcamp_Previews: PreviewProvider {
    static var previews: some View {
        AsyncAwaitBootcamp()
    }
}

 

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.