티스토리 뷰
안녕하세요. 개발자 멍구입니다!
iOS 개발을 하다 보면 "동시성", "데이터 경쟁(data race)", "스레드 안전성" 같은 말들이 자주 들리죠? 처음 들으면 어렵게 느껴질 수 있지만, 오늘은 그런 개념들을 단번에 정리해주는 핵심 키워드 두 가지를 소개해드릴게요.
바로 Actor와 Sendable입니다. 앱이 복잡해지고, 멀티태스킹이 많아질수록 중요해지는 이 개념들, 오늘 알아보겠습니다.
Actor? 데이터 경합 문제를 깔끔하게 해결하는 방법
먼저 Actor부터 볼게요.
"Actor는 일종의 안전한 방입니다." 여러 사람이 동시에 들어와서 방 안의 물건을 엉망으로 만들지 않도록, 한 명씩만 차례대로 들어와서 방 안의 상태를 변경할 수 있도록 해요.
Swift에서 actor는 class처럼 참조 타입이지만, 단 하나의 큰 차이가 있어요. 동시에 여러 스레드에서 접근하더라도 데이터 충돌이 일어나지 않게 보호해주는 장치라는 점이죠. 그 외에도 아래와 같은 특징이 있습니다.
- 내부 상태에 대한 접근을 순차적으로 처리합니다. (상태에 대한 동시 접근을 방지)
- 덕분에 data race 문제를 자연스럽게 피할 수 있어요.
- ❌ 단, class와 달리 상속이 안 되기 때문에 override, final 같은 키워드는 사용할 수 없어요.
한 마디로, Actor는 멀티태스킹 환경에서 우리의 앱이 안전하게 작동하도록 도와주는 수호자라고 볼 수 있겠네요.
💡 참고: Actor는 내부적으로 Sendable 프로토콜을 암시적으로 따릅니다. (즉, 특별히 선언하지 않아도 Sendable로 간주돼요.)
Sendable? 여러 스레드에서 안전하게 전달 가능한 타입
Swift는 구조체(struct)나 열거형(enum)처럼 값 타입을 기본으로 사용하죠. 그런데 동시성 환경에서는 이 값들이 여러 스레드에서 동시에 변경되면 문제가 생길 수 있어요.
그래서 Swift 5.5부터 등장한 게 바로 Sendable입니다.
"Sendable은 어떤 값이 여러 작업(Task) 간에 안전하게 전달될 수 있는지를 나타내는 약속"
Swift 컴파일러는 Sendable을 따르는 타입이라면 여러 스레드 사이에서 마음 놓고 전달해도 괜찮다고 판단하고, 이를 컴파일 타임에 확인해줍니다. 스레딩 문제를 조기에 확인하고, 처리할 수 있도록 해주죠.
Sendable Class 만들 때 주의할 점
기본적으로 Sendable한 구조체, 열거형 등의 값 타입에 비해 클래스를 Sendable하게 만들려면 몇 가지 조건을 지켜야 해요.
- final 키워드가 필요해요 (상속을 막기 위해)
- 변경되지 않는(immutable) 속성만 포함해야 해요
- NSObject 등 Objective-C 기반의 슈퍼 클래스는 사용하면 안됨.
예외적으로, @MainActor로 선언된 클래스는 자동으로 Sendable이 됩니다. 왜냐면 메인 액터가 상태 접근을 하나씩 조절하기 때문이죠.
하지만 이 조건을 만족하지 않는 클래스를 Sendable로 만들고 싶다면?
@unchecked Sendable
을 붙여줄 수 있어요. 이건 말 그대로 “컴파일러야, 내가 책임질 테니 그냥 통과시켜줘!”라는 뜻이에요. 그만큼 신중하게 사용해야 합니다. 😅
이걸 사용하면 개발자가 수동으로 Sendable할 수 있도록 처리해주어야하니 주의해야해요.
Sendable Functions & Closures: 안전하게 값 전달하는 법
함수나 클로저에서도 @Sendable 속성을 사용할 수 있어요.
let sendableClosure = { @Sendable (number: Int) -> String in
return number % 2 == 0 ? "Even" : "Odd"
}
이렇게 정의된 클로저는 내부에서 캡쳐하는 값도 모두 Sendable 타입이어야 해요.
그 외로 Task.detached와 같은 비동기 문맥에서는 Swift가 자동으로 "이건 Sendable 클로저겠지?" 하고 판단해요.
💡Sendable 클로저를 만들 땐 값을 복사해서 쓰고, 값도 안전한 타입이어야 해요!
Sendable Tuples & Metatypes 에서의 Sendable
튜플은 그 내부 요소들이 Sendable이면 전체적으로 Sendable로 간주됩니다. 타입 메타타입 (Int.Type, String.Type)도 암시적으로 Sendable 합니다.
- (Int, String) → 둘 다 Sendable
- (Int, UIView) → UIView는 Sendable 하지 않으므로, 해당 튜플은 Sendable 하지 않음. ❌
마무리 정리: actor와 Sendable 개념, 왜 알아야 할까?
앱이 커질수록 비동기 작업은 피할 수 없고, 비동기 작업이 많아질수록 안전하게 데이터 관리하는 것이 중요해요.
Swift의 Actor, Sendable, @Sendable, @MainActor는 이런 상황에서 에러 없이, 예측 가능한 앱을 만들도록 도와주는 도구예요.특히 요즘 같이 async/await 패턴이 기본이 된 Swift 세계에서는 Sendable과 Actor는 "선택"이 아닌 "필수"라고 할 수 있어요.
앱 규모가 커질 수록 훨씬 복잡하고 많은 스레드 비동기 작업이 필요하고, 그럴수록 data race condition을 주의해야합니다. 따라서actor, Sendable 등의 Swift Concurrency 사용 간의 개념들에 대해 잘 알고 활용해야겠습니다.
지금까지 iOS Data race 해결에 사용되는 개념, 도구인 Actor와 Sendable 적용 케이스 등에 대해서 알아봤어요. 많은 피드백 부탁드려요. 감사합니다!
Reference
Sendable | Apple Developer Documentation
A thread-safe type whose values can be shared across arbitrary concurrent contexts without introducing a risk of data races.
developer.apple.com
'iOS 개발 > 개발자문서 정보' 카테고리의 다른 글
Swift6 동시성, Sendable protocol의 개념 및 중요성 (0) | 2025.05.06 |
---|---|
iOS 개발자 문서, Swift6 소스 호환성 가이드 읽기 (0) | 2025.03.30 |
Swift Concurrency, TaskGroup 효율적인 동시성 제어방법 (0) | 2025.03.17 |
UIKit 버튼 설정, UIButtonConfiguration 개발자문서 개요 (2) | 2024.09.06 |
iOS SwiftUI, GridView 레이아웃 속성 GridItem 개발자문서 읽기 (0) | 2024.08.15 |
- Total
- Today
- Yesterday
- 개발자문서
- swift 기초
- 알고리즘
- Protocol
- Collection
- 백준swift
- SwiftUI
- swift문제
- swift string
- 김프매매
- 스위프트
- 부스트코스
- swift언어
- swift 문자열
- uikit
- 프로그래머스
- swift알고리즘
- 프로토콜
- ios
- Swift 알고리즘
- swift concurrency
- swift
- 알고리즘문제
- createML
- 자연어처리
- swift reduce
- 백준알고리즘
- 컬렉션
- CoreML
- 프로그래머스swift
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |