일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SeSAC
- xcode
- observable
- Firebase Analytics
- Tuist
- 카카오뱅크 ios
- Subject
- KeyPath
- arc
- Firebase
- SwiftUI
- swift 5.9
- swift db
- ios swiftdata
- ribs
- RxSwift
- Subscribe
- JSON
- realm
- swift database
- Swift Tuist
- ios database
- GCD
- Tuist Swift
- Combine
- ios
- swift 6
- swift
- swiftdata
- 네트워크 통신
- Today
- Total
천원의 개발
Swift 6 새로운 기능 본문
안녕하세요. 천원입니다.
오늘은 Swift 6 의 변경점에 대해서 정리하고자 이렇게 글을 작성합니다.
지난 2024년 10월 17일 Xcode 16과 함께 Swift 6가 배포가 되었습니다. Swift 5가 배포된 후 5년 만의 정기 업데이트라고 합니다.
또한 Swift의 10주년 기념의 배포라고 하네요. 공식 문서에 작성된 글들을 보면 Swift 팀에서는 Swift를 APP 개발을 위한 언어가 아닌 다양한 Platform에 지원이 가능한 언어를 목표로 하는 것 같습니다.
Concurrency
Data Race 안전성을 달성하기 위한 여정은 여러 Swift 버전에 걸쳐 진행되었습니다. Swift 5.5에서는 async/await와 Actors가 도입되었고, Swift 5.6에서는 전달 가능한 Sendable Distributed Actor, Swift 5.9에서는 Custom Executors 및 Assertions for Isolation이 추가되었습니다. 그리고 Swift 5.10에서는 Full Data Isolation과 Isolated Globals가 도입되었습니다.
이러한 모든 기능들이 결합되어, 데이터 레이스 안전성을 완전히 보장하는 새로운 옵트인(opt-in) 컴파일러 모드가 제공됩니다. Swift 6가 컴파일 시점에 데이터 레이스 조건을 식별하여 코드의 다른 부분이 공유 데이터를 동시에 접근하고 수정하는 것을 방지하기 때문에, 동시성 프로그래밍이 극적으로 쉬워졌다고 설명했습니다.
각 버전별 기능을 조금 더 자세히 살펴보면
Swift 5.5 - async/await와 Actors
- async/await: 비동기 작업을 작성하고 제어하는 새로운 문법으로, 코드가 비동기적으로 순차 실행되도록 만들어 코드의 가독성을 높입니다. 복잡한 콜백 구조 없이 비동기 함수 호출을 작성할 수 있어 비동기 코드의 가독성과 유지보수성이 개선됩니다.
- Actors: 동시성 문제를 줄이기 위해 고유한 실행 컨텍스트를 가진 객체입니다. 액터는 특정 데이터에 대한 직렬화된 접근을 보장하여 데이터 레이스를 방지합니다. 이를 통해 여러 스레드가 동시에 같은 데이터에 접근하거나 수정할 수 없도록 보호합니다.
Swift 5.6 - Sendable 및 Distributed Actor
- Sendable: 데이터가 다른 스레드로 안전하게 전달될 수 있음을 나타내는 프로토콜입니다. 특정 객체가 스레드 간 전송될 수 있는지를 검사하여 안전하지 않은 데이터 공유를 방지하고, 데이터 무결성을 유지할 수 있습니다. @Sendable 표시를 통해 안전성을 보장합니다.
- Distributed Actor: 다른 시스템이나 네트워크를 통해 통신할 수 있는 액터 유형입니다. 이를 통해 각 액터가 서로 독립적인 노드처럼 분산된 환경에서 작업할 수 있습니다. 분산 액터는 스레드 안전성을 강화하여 동시성 안전성을 높입니다.
Swift 5.9 - Custom Executors 및 Assertions for Isolation
- Custom Executors: 사용자 정의 실행자를 통해 특정 동시성 작업이 어떤 실행 맥락에서 수행될지 정의할 수 있습니다. 이렇게 하면 성능을 최적화하거나 특정 리소스에 액세스할 때 보안을 강화할 수 있습니다. 이는 특히 Actor 시스템의 동작을 제어하여 더욱 안전하고 효율적인 동시성 처리를 가능하게 합니다.
- Assertions for Isolation: 코드가 올바르게 격리되어 있는지 확인하는 검증 기능입니다. 특정 데이터가 적절히 격리되어 다른 스레드로부터 보호되는지 확인하여, 동시성 관련 버그를 사전에 방지할 수 있습니다.
Swift 5.10 - Full Data Isolation 및 Isolated Globals
- Full Data Isolation: 데이터에 대해 완전한 격리를 제공합니다. 즉, 특정 데이터에 대한 모든 접근이 오직 해당 데이터를 소유한 액터를 통해서만 이루어지도록 보장합니다. 이를 통해 다른 스레드나 액터가 데이터를 잘못 수정하지 않도록 강력하게 보호합니다.
- Isolated Globals: 전역 변수를 격리하여, 전역적으로 공유되는 데이터에 대한 안전한 접근을 제공합니다. Swift에서는 전역 상태를
Typed throws
Swift 6에서는 Error를 던질 때 any Error가 아닌 타입의 지정이 가능합니다.
thorws 키워드 뒤의 (ParseError)를 통해서 던질 Error 타입의 지정이 가능합니다.
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
}
제네릭 타입 또한 사용이 가능합니다.
extension Sequence {
func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T] {
// ...
}
}
만약 map 함수를 호출 시 Error 핸들링 할 필요가 경우는 Never를 활용하여 에러를 던지지 않는 함수로 변경이 가능합니다.
~Copyable
Swift 5.9에서 등장한 ~Copyable은 복사할 수 없는 타입을 나타내며 이러한 인스턴스는 다른 곳으로 복사될 수 없습니다. 대신, 이러한 타입의 인스턴스는 참조 또는 transfer 방식으로 전달됩니다.
~Copyable은 Struct, Enum 타입에 사용이 가능하며 인스턴스는 그냥 사용하면 컴파일 에러가 발생합니다. 이때 사용하는 키워드들은 consuming, borrowing, inout 이 있는데 관련해서는 종권님 블로그에 잘 정리되어 있습니다.
struct UniqueResource: ~Copyable {
var value: Int
}
func useResource(resource: consuming UniqueResource) {
// resource는 복사되지 않고, 소유권이 이동합니다.
print(resource.value)
}
복사 오버헤드 제거 ~Copyable을 사용하면 복사할 필요가 없으므로, 데이터가 큰 구조체나 복잡한 객체를 다룰 때 성능을 크게 향상시킬 수 있습니다. 복사 과정에서 발생할 수 있는 메모리 할당 및 초기화 비용을 줄일 수 있습니다.
Swift 6에서는 ~Copyable과 제네릭 타입을 결합하여 다양한 타입에 대해 보다 유연하고 안전한 코드를 작성할 수 있습니다.
protocol Drinkable: ~Copyable {
consuming func use()
}
struct Coffee: Drinkable, ~Copyable { /* ... */ }
struct Water: Drinkable { /* ... */ }
func drink(item: consuming some Drinkable & ~Copyable) {
item.use()
}
drink(item: Coffee())
drink(item: Water())
C++ 상호 운용성
Swift 5.9는 C++와의 양방향 상호 운용성을 도입하여 기존 프로젝트에 Swift를 더 원활하게 통합할 수 있도록 했습니다. Swift 6에서는 C++의 이동 전용 타입, 가상 메서드, 기본 인자, 그리고 map과 optional과 같은 더 많은 표준 라이브러리 타입에 대한 상호 운용성 지원이 확대되었습니다.
Embedded Swift
Swift 6에는 프로그래밍 마이크로컨트롤러와 같은 임베디드 소프트웨어 개발에 적합한 언어 하위 집합 및 컴파일 모드인 Embedded Swift의 미리보기가 포함되어 있습니다. 이 툴체인은 ARM 및 RISC-V 베어메탈 타겟을 지원합니다.
128-bit Intergers
Swift 6에서는 저수준 정수 원시 타입의 집합을 완성하여, 부호 있는 128비트 정수 타입과 부호 없는 128비트 정수 타입을 추가했습니다. 이들은 모든 Swift 플랫폼에서 사용 가능하며, 표준 라이브러리의 다른 고정 폭 정수 타입과 동일한 API를 제공합니다.
// 부호 있는 128비트 정수
let signedInt: Int128 = Int128.max // 최대값
print("부호 있는 최대값: \(signedInt)")
// 부호 없는 128비트 정수
let unsignedInt: UInt128 = UInt128.max // 최대값
print("부호 없는 최대값: \(unsignedInt)")
@DebugDescription
해당 매크로를 통해서 LLDB Print 기능 사용 시 커스터마이징된 포맷을 사용할 수 있습니다.
@DebugDescription
struct Organization: CustomDebugStringConvertible {
var id: String
var name: String
var manager: Person
// ... 더 많은 속성들
var debugDescription: String {
"#\(id) \(name) [\(manager.name)]"
}
}
LLDB로 출력해 보면
(lldb) p myOrg
(Organization) myOrg = "`#100 Worldwide Travel [Jonathan Swift]`"
Swift Testing
Swift 6에서는 새로운 테스트 라이브러리인 Swift Testing이 포함되었습니다. 강력한 API인 새로운 APIs는 쉽게 테스트 코드를 작성할 수 있습니다. #expect 매크로를 활용하여 자세한 테스트 실패 원인을 제공할 수 있습니다. 다양한 arguments로 테스트를 반복할 수 있는 파라미터화 기능을 통해 대규모 코드베이스에서도 효과적으로 사용할 수 있습니다.
For example:
@Test("Continents mentioned in videos", arguments: [
"A Beach",
"By the Lake",
"Camping in the Woods"
])
func mentionedContinents(videoName: String) async throws {
let videoLibrary = try await VideoLibrary()
let video = try #require(await videoLibrary.video(named: videoName))
#expect(video.mentionedContinents.count <= 3)
}
정리한 부분 외에도 여러 변경점이 있으니 공식 문서를 한번씩 참고해 주셔도 좋을 것 같습니다.
https://www.swift.org/blog/announcing-swift-6/
Announcing Swift 6
We’re delighted to announce the general availability of Swift 6. This is a major new release that expands Swift to more platforms and domains.
www.swift.org
여기까지 Swift 6 새로운 기능 정리였습니다.
감사합니다.
참고:
'iOS&Swift🍎 > Swift' 카테고리의 다른 글
Swift ReactorKit Pulse 기능을 학습하기 위한 과정 (0) | 2024.06.27 |
---|---|
Swift Clean Architecture 정리 (1) | 2023.11.23 |
iOS Tuist 프로젝트에 적용하기 (0) | 2023.10.22 |
Swift RIBs RootRIB 설정하기 (0) | 2023.09.09 |
Swift RIBs 튜토리얼 (with StoryBorad) (0) | 2023.08.26 |