Task
내부 또는 async
를 따르는 함수에서 do catch
등을 통해 await
로 비동기적으로 종료되는 태스크의 실행을 캐치 가능import SwiftUI
struct MyStorage {
static func fetchID() async {
print("Async Work")
}
static func fetchID() {
print("Sync Work")
}
}
struct ConcurrencyView: View {
var body: some View {
Text("Hello, World!")
.onAppear(perform: MyStorage.fetchID)
.task {
await MyStorage.fetchID()
}
}
}
Sync Work
Async Work
struct ConcurrencyView: View {
var body: some View {
Text("Hello, World!")
.onAppear(perform: MyStorage.fetchID)
.task {
MyStorage.fetchID()
}
}
}
await
를 쓰지 않고 fetchID()
를 호출했을 때 컴파일러는 동일한 이름의 동기 함수를 실행Sync Work
Sync Work
await
키워드 필수func loginAndAskAndConnet() {
try await withThrowingTaskGroup(of: LoginTaskResult.self, body: { group in
group.addTask(operation: fetchLocation)
group.addTask(operation: askForUserPermission)
group.addTask(priority: .high) {
return .client(try await APIClient.connect())
}
var client: APIClient!
for try await result in group {
if case LoginTaskResult.client(let api) = result {
client = api
break
}
}
let tracer = client.traceEvent
group.addTask(operation: client.logUserIn)
group.addTask {
try await tracer(.login)
}
try await group.waitForAll()
_ = try await tracer(.completedLoginSequence)
})
}
of
를 통해 주어진 태스크 그룹for try await
를 통해 AsyncSequence
를 다루면서 태스크 그룹이 리턴하는 클라이언트 api 데이터를 가져온 뒤 클라이언트의 로그인 태스크 및 이벤트 추적을 동시적으로 진행group.waitForAll()
을 통해 그룹 내에 추가된 모든 태스크가 종료될 때까지 보장user-initiated-qos.cooperative
스레드 풀에서 멀티 스레드를 통해 실행actor MyActor {
private var counter = 0
public func increment() {
counter += 1
}
}
increment()
를 실행하는 호출 순서가 액터가 주관하는 큐에서 실행struct MyModel {
@MainActor func updateItems() {}
@MainActor func clearAllItems() {}
}
struct Logger {
@MainActor var logs: [String]
}
@MainActor struct UIHelpers {
// members
}
@MainActor
와 같은 형식으로 선언된다면 해당 함수 실행이 곧 isolated
된다는 뜻@MainActor
와 같은 형식으로 선언했다면 내부의 모든 데이터, 함수 등이 isolated
되는 게 디폴트이기 때문에 그렇지 않은 대상에 `nonisolted
로 별도로 선언해 주어야 함unownedExecutor
가 존재unowned
참조로서 해당 액터를 실행하는 익스큐터를 반환하는 프로퍼티 변수(익스큐터란 해당 액터가 주관하는 동작을 순차적으로 실행하도록 보장하는 큐)distributed actor Database {
func allUsers() -> [User] { ... }
}
let database = try Database.resolve(id: IP("111.222.333"), using: HTTPSTransport())
let users = try await database.allUsers()
distributed
를 사용한 액터 클래스해당 강의가 나온 시점에
distributed
키워드는 아직 도입되지 않은 상황이었는데, 해당 방법을 통해 액터를 사용할 때의 이점을 설명하고 있다