WWDC 21 - Meet async/await in Swift
https://developer.apple.com/videos/play/wwdc2021/10132/
Concurrency 동시성
: Perform asynchronous and parallel operations.
비동기 및 병렬 작업을 수행
기존의 비동기 작업은 DispatchQueue나 completionHandler를 사용하여 처리했지만,
async / await을 사용하여 비동기(asynchronous) 코드를 작성하면 안전하고, 짧게, 의도가 좀 더 명확한 코드를 작성할 수 있다.
safer, shorter, making it better reflect your intent
기존에는 used completion handlers to query and respond to API calls, and dispatch queues to isolate concurrent access to memory.
Swift concurrency provide clearer code with better error checking at compile time. It replaces the completion handlers with async functions, and uses actors to guarantee safe access to data.
기존 completionHandler 사용
작업을 동기적으로 실행한다면, 작업이 끝날 때까지 다른 작업들은 기다린다.
비동기로 작업을 실행하면, 해당 작업이 끝나든 말든 신경 쓰지 않고 나머지 작업을 동시에 실행. 따라서 이미지 다운로드나 네트워킹 등 작업 시간이 오래 걸리는 것들은 비동기로 처리하는 것이 일반적.
그렇다면, 비동기 처리에서 해당 작업이 언제 끝나는지 어떻게 알 수 있을까
Swift에서는 completionHandler 클로저를 통해 해당 작업이 실제로 끝나는 시점을 알 수 있다.
completionHandler를 사용
completionHandler 사용할 경우, 받아온 데이터 및 에러를 return 하게 된다.
cpletion은 작업이 종료되는 경우 항상 호출이 되어야 하는데, (에러가 발생할 수 있는) 상황마다 개발자가 직접 completion으로 설정을 해주어야 하기 때문에 completion이 호출되지 않는 문제가 발생할 수도 있다.
completionHandler 콜백 형식의 문제점
- 작업 종료 시 completionHandler 호출 누락 가능(잊을 수 있음)
- 오류 처리를 어렵고 장황하게 만듬. 에러 핸들링도 복잡
- 비동기 호출 간의 제어 흐름이 복잡할 때도 문제가 되고
- 매개변수 @escapint(String) -> Void 는 읽기 어려움
=> 이러한 상황 해결 위해 swift 5.5부터 async await 도입.
비동기 코드를 마치 동기 코드인것 처럼 작성 가능.
안전하게, 짧게, 의도를 더 잘 반영하여 코드 작성 가능.
함수 이름 뒤에 async가 붙으면 이 함수는 비동기라는 것을 나타냄.
async 함수를 호출하기 위해서는 await 키워드가 필요.
await 로 마킹된 곳은 잠재적인 suspension point 로 지정됨.
suspend란?
해당 스레드가 다른 동작을 수행할 수 있게 제어권을 놓아주겠다(?) 는 의미 .
스레드 제어권을 시스템에게 넘김…? -> 해당 스레드에서 다른 작업을 먼저 실행할 수 있다.. ?
**
async 호출을 통해 비동기 작업. but async를 사용한다고 해서 한 번에 둘 이상의 작업을 수행한다는 의미는 아님.
async 문법 자체가 동시성을 제공하지는 않음
Task는 Swift가 코드를 병렬로 실행하는 기본 메커니즘. 동시(concurrent)에 실행할 수 있는 .. 를 제공..?
WWDC 21 - Use async/await with URLSession
https://developer.apple.com/videos/play/wwdc2021/10095/
async / await 을 사용하여 URLSession 으로 서버에서 데이터 받아와봄
func fetchData(url: URL) async throws -> [DataModel] {
let (data, response) = try await URLSession.shared.data(from: url)
guard let statusCode = (response as? HTTPURLResponse)?.statusCode,
(200...299).contains(statusCode) else { throw APIError.invalidServerResponse }
let zonesList = try JSONDecoder().decode([DataModel].self, from: data)
return dataList
}
받아와서 사용할 때는 다음과 같이 Task 로 받아와 쓸 수 있음
Task {
do {
self.model = try await apiManager.fetchData()
} catch APIError.invalidURL {
debugPrint(APIError.invalidURL)
} catch APIError.invalidServerResponse {
debugPrint(APIError.invalidServerResponse)
}
}
간편하고 좋은거같다.
'Swift iOS 앱 개발 > Swift' 카테고리의 다른 글
[Swift] Why double is preferred over float? (+ Int / Int32 / Int64) (0) | 2023.04.13 |
---|---|
Swift 언어에 대하여 (0) | 2023.04.13 |
[Swift ARC] Strong Reference Cycles 강한 순환 참조 (0) | 2023.02.07 |
[Swift ARC] strong / weak / unowned references 강한 참조 약한 참조 (0) | 2023.02.07 |
[Swift ARC] Automatic Reference Counting (0) | 2023.01.31 |