티스토리 뷰

Swift

[Swift] Concurrency(6) - Sendable Types

Kim_Baechu 2022. 12. 20. 01:05

태스크 및 액터를 통해 프로그램을 안전하게 동시에 실행할 수 있는 부분으로 나눌 수 있습니다.

태스크 및 액터의 인스턴스 내부에서 변수 및 프로퍼티 같이 가변 상태를 포함하는 프로그램 부분을 동시성 도메인(concurrency domain)이라고 합니다.

 

일부 유형의 데이터는 데이터가 가변 상태를 포함하기 때문에 동시성 도메인들 사이에서 공유될 수 없습니다.

하지만 오버래핑 접근에 대해서는 보호되지 않습니다.

한 동시성 도메인에서 다른 도메인으로 공유할 수 있는 타입을 sendable이라고 합니다.

 

예를 들어, 액터 메서드를 호출할 때 인수로 전달되거나 작업의 결과로 반환될 수 있습니다.

이 장의 앞부분에 있는 예제에서는 동시성 도메인 간에 전달되는 데이터에 대해 항상 안전하게 공유할 수 있는 단순한 값 유형을 사용하기 때문에 전송 가능성(sendability)에 대해 설명하지 않았습니다.

대조적으로, 일부 유형은 동시성 도메인을 통과하는 것이 안전하지 않습니다.

 

예를 들어, 변경 가능한 프로퍼티를 포함하고 이러한 프로퍼티에 대한 액세스를 직렬화하지 않는 클래스는 다른 태스크 간에 해당 클래스의 인스턴스를 전달할 때 예측할 수 없고 잘못된 결과를 생성할 수 있습니다.

sendable프로토콜을 선언하여 유형을 전송 가능하도록 표시합니다.

그 프로토콜에는 코드 요구 사항이 없지만 Swift가 적용하는 의미론적(semantic) 요구 사항이 있습니다.

 

일반적으로 유형을 전송할 수 있는 세 가지 방법이 있습니다.

  • 값 유형이며 변경 가능한 상태는 다른 전송 가능한 데이터(예: sendable 저장 프로퍼티가 있는 구조체 또는 sendable 관련 값이 있는 열거형)로 구성됩니다.
  • 변경 가능한 상태가 없으며 변경 불가능한 상태는 다른 sendable 데이터(예: 읽기 전용 프로퍼티만 있는 구조체 또는 클래스)로 구성됩니다.
  • @MainActor로 표시된 클래스 또는 특정 스레드 또는 대기열에서 해당 프로퍼티에 대한 액세스를 직렬화하는 클래스와 같이 변경 가능한 상태의 안전을 보장하는 코드를 가지는 타입

sendable 프로퍼티만 가진 구조체나 sendable 연관 값만 가지는 열거형 처럼 몇몇 타입은 항상 sendable 합니다.

예:

struct TemperatureReading: Sendable {
    var measurement: Int
}

extension TemperatureLogger {
    func addReading(from reading: TemperatureReading) {
        measurements.append(reading.measurement)
    }
}

let logger = TemperatureLogger(label: "Tea kettle", measurement: 85)
let reading = TemperatureReading(measurement: 45)
await logger.addReading(from: reading)

TemperatureReading은 전송 가능한 속성만 있는 구조체이며 public 또는 @usableFromInline으로 표시되지 않으므로 암시적으로 전송 가능합니다.

다음은 전송 가능 프로토콜 준수를 암시하는 구조체 버전입니다.

struct TemperatureReading {
    var measurement: Int
}
댓글
공지사항