안녕하세요!
애플 디벨로퍼 아카데미 @POSTECH 4기 Ethan입니다.
Swift Concurrency를 공부하다 보면 **데이터의 안전성(Data Safety)**과 격리(Isolation) 개념을 자주 접하게 됩니다.
동시성 환경에서 여러 작업(Task)들이 동일한 데이터를 다룰 때, 데이터의 일관성과 안정성을 보장하는 것이 매우 중요한데요.
오늘은 그 기초가 되는 값 타입과 참조 타입의 차이를 먼저 정리해보겠습니다.
값 타입(Value Type)이란?
값 타입은 데이터를 복사해서 전달하는 타입입니다.
Swift에서 struct, enum, tuple이 대표적인 값 타입입니다.
struct User {
var name: String
var age: Int
}
var user1 = User(name: "Ethan", age: 25)
var user2 = user1 // 복사 발생
user2.name = "Chris"
print(user1.name) // Ethan
print(user2.name) // Chris
특징
- 대입하거나 함수 인자로 전달할 때 값 자체가 복사됨
- 원본과 사본이 완전히 독립적
- 동시성 환경에서 데이터 충돌 가능성이 낮음
즉, Task들이 같은 값 타입 데이터를 동시에 사용해도 서로의 상태에 영향을 주지 않습니다.
Swift가 Struct 중심 언어인 이유가 바로 여기에 있습니다.
참조 타입(Reference Type)이란?
참조 타입은 데이터를 복사하지 않고 참조를 전달하는 타입입니다.
Swift에서 class가 대표적인 참조 타입입니다.
class User {
var name: String
init(name: String) {
self.name = name
}
}
var user1 = User(name: "Ethan")
var user2 = user1 // 참조 전달
user2.name = "Chris"
print(user1.name) // Chris
print(user2.name) // Chris
특징
- 대입하거나 함수 인자로 전달할 때 **메모리 주소(참조)**만 전달
- 원본과 사본이 동일한 인스턴스를 바라봄
- 동시성 환경에서 데이터 충돌 가능성 높음
즉, 여러 Task에서 같은 클래스 인스턴스를 동시에 수정하면 예측하지 못한 버그나 데이터 손상이 발생할 수 있습니다.

동시성에서 값 타입이 중요한 이유
Swift Concurrency의 핵심 목표 중 하나는 데이터 안전성 보장입니다.
다중 스레드 환경에서 동일한 데이터를 여러 곳에서 동시에 읽고 쓸 경우 **데이터 경쟁(Race Condition)**이 발생할 수 있는데요.
값 타입은 복사를 통해 각 Task가 독립적으로 데이터를 다루기 때문에 충돌 위험이 낮습니다.
반면, 참조 타입은 같은 인스턴스를 여러 Task에서 동시에 수정하면 비정상적인 상태가 발생할 수 있습니다.
따라서 Swift는 Struct(값 타입) 중심 설계를 권장하며, 참조 타입을 사용할 경우에는 Actor나 Sendable 프로토콜을 활용해 동시성 안전성을 확보해야 합니다.
마무리
오늘은 Swift Concurrency에서 값 타입과 참조 타입의 차이를 중심으로 데이터 안정성을 살펴봤습니다.
정리하면 다음과 같습니다.
- 값 타입: 복사로 전달 → 독립적 → 동시성 환경에서 안정적
- 참조 타입: 참조로 전달 → 공유됨 → 동시성 환경에서 충돌 가능성 ↑
- Swift는 기본적으로 Struct 기반 설계를 권장
다음 글에서는 이 개념을 확장해서 Sendable 프로토콜과 컴파일러 검사, 그리고 Actor를 활용한 데이터 격리까지 다뤄보겠습니다.
참고 자료
'Swift' 카테고리의 다른 글
| Swift Concurrency - Sendable 프로토콜과 컴파일러 검사 (2) | 2025.08.20 |
|---|---|
| Swift Concurrency - Task와 TaskGroup (3) | 2025.08.19 |
| Swift - async / await 알아보기 (6) | 2025.08.14 |
| Swift Concurrency / 동시성과 병렬성의 차이 (6) | 2025.08.12 |