Swift Sendable: iOS 개발에서 스레드 안정성 주도하기
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- iOS 개발자
- 중급~고급 수준 (Swift 병렬 프로그래밍 개념 이해 필요)
핵심 요약
Sendable
프로토콜은 스레드 간 안전한 데이터 공유를 보장하는 Swift의 핵심 기능- 값 타입(struct/enum)은 불변성(immutable)을 유지하면 자동
Sendable
- 참조 타입(class)은 불변성 또는 락(NSLock)으로 스레드 안정성 확보 필요
- Actor는 내장 스레드 안전성 제공, 자동
Sendable
섹션별 세부 요약
1. Sendable의 목적과 중요성
- 데이터 레이스(Data Race) 방지: 병렬 작업에서
items
,totalPrice
동시 수정으로 인한 메모리 손상, 불확실한 계산 방지 - Sendable은 스레드 간 안전한 데이터 전달을 보장하는 Swift의 철학
- Sendable 미구현 시 런타임 크래시 발생 가능성
2. 값 타입의 Sendable 구현
- 불변성(immutable)을 가지는 struct/enum은 자동
Sendable
struct User: Sendable {
let id: UUID
let name: String
}
Sendable
인 경우만 Sendable
프로토콜 준수 가능String
, Int
, Array
, Dictionary
3. 참조 타입의 Sendable 구현
- 불변성으로 전환:
final class Configuration: Sendable {
let apiKey: String
let baseURL: URL
}
final class AtomicCounter: Sendable {
private let lock = NSLock()
private var _value: Int = 0
func increment() { lock.withLock { _value += 1 } }
}
4. Actor로 스레드 안정성 확보
- Actor는 내장 스레드 안전성 제공, 자동
Sendable
actor DataCache {
private var cache: [String: Any] = [:]
func store(key: String, value: Any) { cache[key] = value }
}
5. Sendable 사용 시 주의사항
- 변경 가능한 속성(mutable)은
Sendable
준수 불가 - 고차함수에서
@Sendable
명시:
func executeAsync(operation: @Sendable @escaping () async throws -> Void) {
Task { try await operation() }
}
Sendable
제약 추가:func process(_ items: [T]) async { ... }
결론
- 스레드 안정성을 위해
Sendable
준수 타입 사용, 불변성과Actor
활용 - 값 타입은 불변성 유지, 참조 타입은 락 또는 불변성으로 처리
- 제네릭 함수와 고차함수에서
Sendable
제약 명시 필수 - Actor를 사용해 복잡한 상태 관리 시 스레드 안전성 보장