<@Sendable은 무엇인가?> 2. Sendable Protocol

SteadySlower·2023년 7월 6일
0

iOS Development

목록 보기
24/38

지난 번 포스팅에서 @Sendable에 대해 알아보기 위해서 @Sendable이 존재하는 이유인 Race Condition에 대해서 알아봤습니다. 이번 포스팅에서는 Sendable protocol에 대해서 알아봅니다.

Sendable 프로토콜

Sendable | Apple Developer Documentation

위 공식문서의 정의를 보면 복사를 통해서 동시성 영역 (= 다른 쓰레드)에 안전하게 전달할 수 있는 값을 가진 타입이라고 합니다. 즉 reference를 전달하는 것이 아니라 value를 전달해야지만 안전할 수 있다는 것이죠. 하지만 이 protocol을 채택하기 위해서 반드시 reference type이어야 하는 것은 아닙니다.

Sendable을 준수하는 타입들

마찬가지로 공식문서입니다. Sendable을 채택할 수 있는 타입들입니다. value 타입은 당연히 가능합니다. 다만 struct의 경우 모든 member들이 Sendable해야 하고 enum의 associated value도 마찬가지입니다.

class와 같은 Reference type도 Sendable이 될 수 있지만 mutable해서는 안됩니다.

다만 mutable한 Reference type 중에 상태에 대한 접근을 내부적으로 통제할 수 있는 reference 타입은 가능합니다. 예를 들면 직접 property를 업데이트를 허용하지는 않고 반드시 method를 통해 업데이트하도록 하는데 그 method가 Race condition을 일으키지 않는 경우입니다. (말로만 설명하니까 어렵네요…)

특히 actor라는 타입을 활용하면 쉽게 상태에 대한 접근을 내부적으로 통제할 수 있는 reference 타입을 만들 수 있습니다. 나중에 포스팅을 통해서 소개하도록 할께요!

마지막으로 우리가 알아보고 있는 functions 와 closures에 대한 내용입니다. 기본적으로 함수(클로저)는 reference 타입입니다. 하지만 함수(클로저)는 프로토콜을 채택할 수 없습니다. 따라서 @Sendable attribute를 사용해서 Sendable임을 선언합니다.

함수(클로저)가 Sendable하기 위해서는 켭쳐하는 타입들이 (= 파라미터)가 전부 Sendable이어야 하고 value 방식으로 전달되어야 합니다. (복사)

TCA로 돌아가면…

struct WeatherClient {
  var forecast: @Sendable (GeocodingSearch.Result) async throws -> Forecast
  var search: @Sendable (String) async throws -> GeocodingSearch
}

제가 애초에 이 포스팅을 작성하기 시작한 이유는 위 클로저들 앞에 각각 붙은 @Sendable의 정체를 밝혀내기 위해서 였습니다.

각각의 클로저는 다른 스레드로 보내서 실행될 수 있도록 하기 위해서 @Sendable attribute가 붙은 것이죠. WeatherClient에 정의된 각각의 클로저는 네트워크 통신을 하는 클로저이기 때문에 메인 스레드를 잡아 두기 보다는 다른 스레드로 보내는 것이 합리적이기 때문입니다.

위에서 설명한 정의에 의하면 위 클로저들이 캡쳐하는 타입들도 전부 Sendable이어야 합니다.

마치며…

이제 @Sendable의 정체는 알았습니다. 하지만 아직 이 시리즈는 끝나지 않았는데요. Sendable을 공부하면서 알게된 actor라는 타입에 대해서 다음 포스팅에서부터 알아보도록 하겠습니다.

profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글