시작 하기에 앞서 SwiftConcurrency 1편부터 이어지는 내용임으로 1편부터 보고 와주시길 바랍니다!
시작 하겠습니다.
각 비동기 작업이
독립
적으로 실행되도록 합니다.
즉독립적
이기에 데이터 레이스를 방지 할수 있죠.
각 Task는 독립적으로 실행됩니다. Task 간 순차적으로 실행됨으로,
각 Task는 자신만의 흐름을 가지고 있습니다.
작업은 처음부터 끝까지 순차적으로 수행함을 보장합니다.
Task에서 비동기적으로 실행됩니다. 다른 Task의 완료를 기다리지 않고 병렬로 실행 될수 있죠.
각 Task는 스스로 상태,실행 흐름을 가지고 있어, 다른 Task와 독립적으로 동작합니다.
즉, Task 간의 간섭을 방지합니다.
Task {
var localData = "떼이타"
localData += " 추가염"
print(localData) // "떼이타 추가염"
}
Task {
var localData = "Swift"
localData += " Concurrency"
print(localData) // "Swift Concurrency"
}
Actor 내부 상태는 직렬화된 접근이 보장되며, 서로 다른 작업에서 접근 할 수 있는 상태를 격리 시켜 data race를 제거할수 있습니다.
외부에서 접근할수 없도록 상태를 캡슐화 합니다.
actor
에 대한 접근(상태 접근)은직렬화
되므로, 동시에 여러 Task가 동일한 상태를 변경할 수 없습니다.
모든
actor
는sendable
을 압시적 준수 합니다.actor
는 참조 타입이지만, 내부의 상태를 격리하여, 독립성을 갖습니다.
Task.detached
는 독립적인 비동기 작업을 생성합니다.
actor의 독립성을 종속하지 않습니다. 즉 외부에 있는것으로 간주됩니다.
다만,Actor
상태를 직접 변경 불가능 하지만, 메서드를 통해서는 가능합니다.
actor Kitchen {
private var food: String = "Apple"
func getFood() -> String {
return food
}
func setFood(newFood: String) {
food = newFood
}
}
let kitchen = Kitchen()
// Task를 사용하여 Actor의 상태에 접근
Task {
// Task는 현재 컨텍스트를 상속받기 때문에 Actor의 상태에 접근할 수 있습니다.
await kitchen.setFood(newFood: "Banana")
print(await kitchen.getFood()) // "Banana"
}
// Task.detached를 사용하여 Actor의 상태에 접근
Task.detached {
// Task.detached는 Actor의 격리된 상태에 직접 접근할 수 없습니다.
// Actor의 메서드를 통해서만 접근할 수 있습니다.
print(await kitchen.getFood()) // "Banana"
}
메인 쓰레드에서 동작함을 나타내는 Actor 입니다.
메인 쓰레드에서 해야하는 UI작업은 MainActor에서 해줘야 합니다.
작업이 손실 되지 않고 완료 될수 있도록 보장하는 방법입니다.
actor Human {
var Hands: [Hand] = []
func deposit(Hands: [Hand]) async {
var current = self.Hands
current += Hands
self.Hands = current
}
}
let island = Island()
Task {
var apples: [Hand] = [Hand(), Hand()]
await island.deposit(apples: apples)
}
저번에 다루었던 내용을 더 다듬어서 적용해 보았는데
이해가 되셨을까요..? 궁금한 사항이 있다면 댓글로 남겨주세요!
다음 편은 distributed actor 로 돌아오겠습니다!