반응형
swift concurrency 에 actor 라는 개념이 있다. 가장 간단하게 actor 를 사용하는 예제를 만들어 보았다. ( with a little help of gpt )
횟수를 카운트 하는 매우 간단한 카운터 class/actor이다. 카운터를 생성해서, 동시에 수행되는 두 태스크에서 동시에 카운팅이 이루어진다.
import Foundation
actor MyActorCounter {
var counter = 0
func incrementCounter() {
counter += 1
}
}
class MyClassCounter {
var counter = 0
func incrementCounter() {
counter += 1
}
}
func testActorCounter() async -> Void {
let counter = MyActorCounter()
await Task {
let task1 = Task {
for _ in 0 ..< 10000 {
await counter.incrementCounter()
}
}
let task2 = Task {
for _ in 0 ..< 10000 {
await counter.incrementCounter()
}
}
await task1.result
await task2.result
}.result
print("actor counter count :", await counter.counter)
}
func testClassCounter() async -> Void {
let counter = MyClassCounter()
await Task {
let task1 = Task {
for _ in 0 ..< 10000 {
counter.incrementCounter()
}
}
let task2 = Task {
for _ in 0 ..< 10000 {
counter.incrementCounter()
}
}
await task1.result
await task2.result
}.result
print("class counter count :", counter.counter)
}
await testActorCounter()
await testClassCounter()
이렇게 한번은 actor 카운터로, 다른 한번은 class 카운터로 테스트를 해 보았다. 과연, 카운트 결과는 어떨까?
actor counter count : 20000
class counter count : 12220
두 개의 카운터에서 각각 10000을 카운팅하므로, 마지막 결과는 20000이 되어야 한다.
class 카운터의 결과는 할 때마다 바뀐다. 하지만 actor 카운터는 언제나 정확한 카운트 결과를 보여준다.
두 개의 카운터의 정의는 class 라는 키워드만 actor 라는 키워드로 바꾸었고, 카운터를 사용할 때, await 를 붙여주어야 하는 부분들만 잘 수정해 주면, race condition 으로 인한 누락된 카운트 문제가 해결된다.
class 와 actor 구현의 차이점을 비교해보면 다음과 같다.
counter 객체의 method 를 호출할 때, 변수의 값을 확인할 때, await 키워드가 추가된다.
728x90
'프로그래밍 > SWIFT' 카테고리의 다른 글
SwiftUI] StateObject, Published, ObservableObject (0) | 2023.07.11 |
---|---|
[유튭링ㅋ] Mastering Concurrency in iOS (0) | 2023.06.22 |
SWIFT 기초] 배열 슬라이싱 python과 swift 비교 (0) | 2023.03.02 |
[SwiftUI] @State, struct, class (0) | 2022.12.19 |
[Swift] publishing changes from background threads is not allowed; make sure to publish values from the main thread (0) | 2022.11.21 |