일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Swift
- weak
- 풀이
- 이스케이핑
- 스위프트
- RxSwift
- concurrency
- 프로퍼티
- 알고리즘
- observable
- 리스트뷰
- 연산자
- 차이
- 해시
- 옵셔널
- 자바
- rx
- 클로저
- 생명주기
- 구조체
- 백준
- 안드로이드
- Self
- ios
- noncopyable
- 프로그래머스
- 프래그먼트
- Subject
- View
- async
- Today
- Total
study record
[Swift Concurrency] Strict Concurrency Checking 본문
Introduction
Swift Concurrency란?
- Swift 5.5부터 도입된 비동기 프로그래밍 모델
- async/await, Task, actor 등을 통해 동시성 프로그래밍을 쉽게, 그리고 안전하게 작성할 수 있도록 지원
- 목적: 성능 향상 + 코드 안전성 강화(Data Race 제거)
핵심 기법: Sendable checking 및 actor 기반 상태 격리
Problem
기존 코드와의 호환성 문제
- Concurrency 도입 전, Swift 생태계에는 이미 수많은 코드가 존재
이러한 기존 코드는:
- Sendable, @MainActor 같은 동시성 어노테이션이 없음
- 동시성 도입 시 오류가 발생하거나 빌드가 막힘
Sendable, @MainActor 같은 동시성 어노테이션 누락에 따른 오류나 진단은
Swift 5에서는 대부분 무시되거나 경고 수준이고,
Swift 6에서는 "엄격한 동시성 검사(strict concurrency checking)"가 기본이라 오류로 바뀌게 된다.
Strict Concurrency checking
- Swift 6에서 기본이 되는 모드로, 동시성 오류를 컴파일 타임에 오류로 잡는 모드
- Sendable, @MainActor, @Sendable 누락 또는 잘못된 사용 검사
- 동시성 버그를 미리 방지해서 앱 안정성 향상
Concurrency checking mode
1) Strict concurrency checking
- Sendable 채택 누락이나 글로벌 액터 어노테이션 누락이 확인
- Swift 6에서는 대부분 오류(error)로 처리, actor, async
2) Minimal concurrency checking
- Sendable 누락이나 글로벌 액터 어노테이션 누락이 경고(warning)로 처리
- 주로 경고 또는 무시
하위 스코프의 검사 모드 결정 기준
부모 스코프가 최소 모드(Minimal)이고, 다음 조건 중 하나라도 해당되면 자식 스코프는 엄격 모드(Strict)를 갖습니다:
- 명시적인 글로벌 액터 속성이 붙은 클로저
- async 또는 @Sendable 타입의 클로저 혹은 자동 클로저
(단, 클로저 타입 추론에 부모 스코프의 모드가 영향을 줄 수 있음) - nonisolated 또는 글로벌 액터 속성이 명시된 선언
- async 또는 @Sendable이 명시된 함수, 메서드, 이니셜라이저, 접근자, 변수, 서브스크립트
- actor 선언
이외의 경우에는 부모 스코프와 동일한 모드를 사용합니다.
Swift/Xcode settings for concurrency checking
- Swift Language Version을 Swift 6로 변경
- 6로 변경하기 전 Build Setting 옵션 중 Strict Concurrency Checking을 활성화
- Swift 5.x에서 -warn-concurrency 컴파일 플래그를 사용
✅ 동시성 환경에서 Data Race가 발생할 가능성이 있는 곳에서 에러 또는 경고를 표시
✅ 프로젝트를 Swift 6로 올리기 전에 사전 점검!
Strict Concurrency checking
swift 5
swift 6
Problem 1
@Sendable 클로저에서 비-Sendable 타입을 캡처하면 컴파일 오류
swift 5
swift 6
Problem Solving
@unchecked 활용 또는 actor 사용
- unchecked는 개발자가 데이터 레이스로 부터 안전한지 직접 검증해야 함
- actor가 swift가 선호하는 의도하는 방향으로 생각됨.
Problem 2
swift 5
swift 6
Swift 6부터는 함수 파라미터가 @Sendable이면 기본적으로 @escaping으로 취급
Problem Solving
점진적인 migration을 위한 도구
- @unchecked Sendable: 위험을 감수하고 Sendable 수동 선언
- @preconcurrency: Swift Concurrency를 기존 코드에 점진적으로 적용할 수 있도록 설계
@preconcurrency
- Swift 6의 엄격한 동시성 검사에서, 기존 코드가 갑자기 에러 나지 않도록 보호해주는 호환성 속성
- "pre-concurrency" → 동시성 기능 도입 전에 작성된 코드라는 뜻
- 이 속성을 붙이면, Swift 6의 엄격한 검사(strict concurrency checking)에서 일부 오류를 경고로 완화하거나 무시하게 함
- Swift Concurrency를 기존 코드에 점진적으로 적용할 수 있도록 설계
✅ 선언에 적용된 @preconcurrency의 의미
- 어떤 타입(예: 클래스, 구조체, 프로토콜 등)의 선언에 @preconcurrency를 적용하면,
해당 선언이 동시성 지원을 위해 바뀌었지만, Swift 5에서는 기존처럼 느슨하게 취급하라는 의미
✅ import 문에 적용된 @preconcurrency의 의미
- import 모듈명 앞에 @preconcurrency를 붙이면,
그 모듈 안의 타입이 Sendable, @MainActor 등을 제대로 지정하지 않았더라도 엄격한 동시성 오류를 완화(경고 또는 무시)해준다. - 단, 그 타입이 명시적으로 Sendable을 선언했으나 사용 조건을 만족하지 못한 경우,
경고(warning)는 발생할 수 있다. - 그러나 이 경우에도 Swift 6 모드에서 오류가 아닌 경고 수준으로 판단된다.
- Add @preconcurrency to suppress Sendable-related warnings from module MyModule
Sendable 적합성 작동 기준
1. 암묵적으로 Non-Sendable 타입이 필요한 곳에서 사용될 경우:
- @preconcurrency import를 통해 임포트된 타입이면:
- 그렇지 않으면 일반적인 오류 발생 + @preconcurrency import 사용 권장 메시지 출력
2. 명시적으로 Non-Sendable 타입이 필요한 곳에서 사용될 경우:
- @preconcurrency import를 통해 임포트된 타입이면:
- 그렇지 않으면 일반적인 오류 발생
3. @preconcurrency가 더 이상 필요 없게 된 경우:
- 해당 속성이 사용되지 않았다고 판단되면, 이를 제거하라는 경고가 출력됨
(단, 어떤 경우가 "사용되지 않음"인지에 대한 구체적인 기준은 아직 정의되지 않음)
@preconcurrency가 붙은 Sendable 프로토콜
기존에 존재하는 많은 프로토콜은 실질적으로 Sendable 타입을 요구하지만, 초기에는 이를 명시할 수 없었다.
이런 프로토콜이 동시성에 맞게 업데이트되면, 대개 Sendable을 상속하게 된다.
하지만 이렇게 하면, 해당 프로토콜을 채택하고 있던 기존 타입들이 자동으로 Sendable로 간주되면서 오류가 발생할 수 있다.
Error와 CodingKey 프로토콜: 기존 타입들이 오류 대신 경고로 진단
@preconcurrency protocol Error: Sendable
@preconcurrency protocol CodingKey: Sendable
> The Error and CodingKey protocols will adopt Sendable in a @preconcurrency context so that existing conformers do not immediately break in Swift 6.
Swift Concurrency Migration Strategy
- Swift 6는 강력한 동시성 보장, 그러나 호환성 이슈 존재
- @preconcurrency를 통해 기존 코드와의 안정적 연결 유지
- 오류/경고 발생 → 다른 모듈의 타입이면 @preconcurrency import로 임시 억제
- 외부 모듈이 Sendable 도입 시 경고 발생 → 버그 수정
- @preconcurrency가 불필요해지면 경고 → 제거
- 점진적인 Swift 6 대응 및 Sendable 검사 도입 지원
- 점진적 마이그레이션으로 실질적인 생산성 유지 + 미래 호환성 확보
참고
'Swift > Concurrency' 카테고리의 다른 글
[Swift Concurrency] Optimize with Instruments (0) | 2025.04.28 |
---|---|
[Swift Concurrency] AsyncStream, AsyncThrowingStream, Continuation이란? (0) | 2024.01.30 |
[Swift Concurrency] Intermediate async/await & CheckedContinuation (0) | 2023.06.11 |
[Swift Concurrency] Custom Asynchronous Sequences With AsyncStream (0) | 2023.05.29 |
[Swift Concurrency] AsyncSequence & Intermediate Task (0) | 2023.05.24 |