1. Actor 의 등장배경

2. Actor

Sendable 프로토콜을 준수하는 Swift의 한 타입입니다.

Sendable 프로토콜을 준수하는 Swift의 한 타입입니다.

<aside> 👉 Actor는 단순히 Swift의 타입 중 하나입니다. Struct, Enum, Class 등과 비슷한 능력을 가지고 있습니다. 특히 Class와 비슷한데, Actor도 Class와 같은 참조 타입이기 때문입니다. 프로퍼티, 이니셜라이저, 메서드, subscript 등을 가질 수 있고, 프로토콜 conform이나 extension을 통한 확장도 가능합니다.(단, 상속은 지원하지 않습니다)

</aside>

<aside> ❓ Actor Isolation: Actor의 mutable한 상태를 외부로부터 고립시켜 보호하는 개념

</aside>

Untitled

위와 같이 동시성의 바다 위에 떠 있는 섬 Actor가 있고, 섬 외부인 바다로부터 보호받고 있는 양과 파인애플이 있다고 해 봅시다. 이때 Sheep은 Class(참조타입), Pineapple은 Struct(값 타입)입니다.

간단히 코드로 구현하면 다음과 같습니다.

actor Island {
    // Class 타입 프로퍼티
    var animal: [Sheep]
    // Struct 타입 프로퍼티
    var food: [Pineapple]

    // 섬에 있는 자원 정보
    func calculate() {
        let totalBrix = food.indices.reduce(0) { total, nextIndex in
            total + food[nextIndex].brix
        }
        print("파인애플 총 당도: \\(totalBrix)")

        Task {
            let sheepNames = animal.map { $0.name }
            print("첫번째 양 이름은 \\(sheepNames[0])입니다.")
        }

        Task.detached {
            let highBrixPineapples = await self.food.filter { $0.brix == 12 }
            print("당도 12: \\(highBrixPineapples.count)개")
        }
    }

    // Class 반환 함수
    func adoptPet() -> Sheep {
        return animal[0]
    }

    // Struct 반환 함수
    func getFood() -> Pineapple {
        return food[0]
    }

    /// Initializer
    init(animal: [Sheep], food: [Pineapple]) {
        self.animal = animal
        self.food = food
    }

이 actor를 다음과 같이 사용하면, class 타입인 Sheep을 사용할 때 많은 에러가 발생합니다.

Untitled

“Sendable” 프로토콜을 준수하지 않는 Sheep 클래스는 actor의 경계를 넘어갈 수 없다는 것입니다. 즉 Sendable이 아니면 actor 밖으로 전달될 수 없습니다.

Data Race가 생길 수 있는 코드

class Counter {
	let counterName = "Counter Class"
	var count = 0
	
	func increment() -> Int {
		count = count + 1
		return count
	}
}
let counter = Counter()
Task.detached {
	print(counter.increment())
}

Task.detached {
	print(counter.increment())
}