Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

주니곰의 괴발노트

Swift - Concurrency 본문

iOS

Swift - Concurrency

Jhe2 2023. 5. 13. 15:44

 Swift에서의 동시성

Swift에서 비동기 및 병렬 코드를 작성하기 위한 방법을 지원

비동기 코드는 일시중지 되었다가 추후에 다시 실행될 수 있음 

쓰레드를 점유하지 않으며 해당 쓰레드에서 다른 작업을 수행할 수 있음

다시 실행되는 쓰레드는 다른 쓰레드에서 동작될 수 있음

 

 

 Asynchronous Functions 사용하기

활용방법

 클로저 이용

listPhotos(inGallery: "Summer Vacation") { photoNames in
    let sortedNames = photoNames.sorted()
    let name = sortedNames[0]
    downloadPhoto(named: name) { photo in
        show(photo)
    }
}

기존처럼 클로저로 수행되는 동작을 다음과 같이 바꿀 수 있음

 

 Async Functions 이용

// async function 정의
func listPhotos(inGallery name: String) async -> [String] {
    let result = // ... some asynchronous networking code ...
    return result
}

// async function 사용
let photoNames = await listPhotos(inGallery: "Summer Vacation")
let sortedNames = photoNames.sorted()
let name = sortedNames[0]
let photo = await downloadPhoto(named: name)
show(photo)

메서드를 정의할 때는 파라미터의 끝, '->' 직전에 'async' 키워드를 입력

에러를 던지는 함수와 같이 정의할 경우 async throws 순서로 입력

사용시에는 await 키워드를 이용하여 중단할 지점을 선택

에러를 던지는 함수일 경우 try await 순으로 입력

 

실사용 예

 

 클로저 이용

콜백함수 이용한 네트워킹
콜백함수를 이용한 네트워킹
콜백함수와 Result타입을 이용한 네트워킹

위와 같이 콜백블록을 이용한 메서드는 들여쓰기가 많음

개발자가 에러발생 지점에 콜백함수를 호출하지 않는다거나 하는 실수의 우려가 많음

 

Async Functions 이용

async를 이용한 네트워킹

 

async function을 이용하면 코드를 간결하게 작성할 수 있음

 

SwiftUI에서의 Async Functions 이용

실사용 예 (SwiftUI)

.onAppear { } 메서드는 비동기작업을 지원하지 않기 때문에 동기와 비동기간의 간극을 없애기 위하여 Task { } 사용

DispatchQueue의 global과 비슷

 

 

 Function 외에서의 활용

 

프로퍼티

변수에도 async 사용가능, setter는 없음

 

시퀀스

반복문에서 async 사용가능

 

 

 Async Function을 이용하여 병렬작업 수행하기

각각에서 await 적용

 

let firstPhoto = await downloadPhoto(named: photoNames[0])
let secondPhoto = await downloadPhoto(named: photoNames[1])
let thirdPhoto = await downloadPhoto(named: photoNames[2])

let photos = [firstPhoto, secondPhoto, thirdPhoto]
show(photos)

await 키워드로 async function을 호출하면 한번에 하나의 비동기 코드만 실행

위의 경우, 사진의 다운로드 시작이 순차적으로 시작됨

따라서 세 번째 사진이 다운로드 시작되기 전에 첫 번째 사진의 다운로드가 완료될 수 있음

 

각각에서 async 적용 후 마지막에 await 적용

async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])

let photos = await [firstPhoto, secondPhoto, thirdPhoto]
show(photos)

위와 같이 async let 을 이용하며 세 사진들이 동시적으로 다운로드가 진행됨

따라서 첫 비동기 작업이 추후 작업에 영향을 미치는지 아닌지를 판단하여 실제 코드에 맞는 동작을 수행

 

 

 동작방식

 

일반 함수

네트워크 호출시 작동상태

 

 

Async Function

네트워크 요청 후 일시정지

작업을 요청하면 일시중단되면서 시스템에게 쓰레드의 제어권을 전달

 

async method의 제어권 소유
async가 suspended된 다음 다른 작업 실행 예시

시스템에서는 시스템이 중요하다고 판단하는 작업을 실행

Async Function의 작업이 완료되면 다시 쓰레드의 제어권을 시스템에게서 가져온 후 나머지 작업 수행

await 키워드는 항상 Async Function가 일시중지된다는 의미가 아니라 될 수도 있다는 것을 의미

 

 

 Apple 자체 API 내부 변화

API들의 콜백블록
기존 콜백블록들이 async 적용된 모습(Swift 5.5)

기존 콜백블록으로 작성되어있던 메서드들이 Swift 5.5 이후, async가 적용

 

 

 참고

https://developer.apple.com/videos/play/wwdc2021/10132/

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/

https://tech.devsisters.com/posts/crunchy-concurrency-swift/

'iOS' 카테고리의 다른 글

Swift - Generic  (0) 2023.06.02
SwiftUI - Search Bar 구현  (0) 2023.05.11
Swift - 열거형  (0) 2023.03.12
Swift - Extensions  (0) 2023.03.05
Swift - Concurrency (동시성)  (0) 2023.02.26
Comments