
(※ hackingWithSwift의 글을 번역한 것으로 아래 출처를 남겨두었습니다. 약간의 오역이 있을 수 있으니 지적해주시면 감사드리겠습니다.)
"sendable(보낼 수 있는)" 데이터를 지원한다는 것 같은데, 여기서 sendable은 다른 스레드로 안전하게 보낼 수 있다는 것이다. 새로운 Sendable 프로토콜과 @Sendable 속성을 사용하면 된다고 한다.
아래는 스레드 간 보낼 때 본질적으로 안전한 것이며, Sendable 프로토콜을 따르도록 업데이트 되었다. (Sendable 프로토콜이 이미 내장되어있으니 따로 설정하지 않아도 된다.)
custom type에 관해서는, 우리가 만드는 것에 따라 달렸다.
작업을 동시적으로 하고 싶다면 함수나 클로저에 @Sendable 속성을 사용할 수 있고 우리가 곤란하게 되지 않게끔 여러 규칙들을 강제할 수 있다. 예를 들면, Task 생성자 안에 넣은 연산이 @Sendable로 표기되는 것이다. 이것이 허용되는 이유는 Task에 의해 캡쳐된 값이 상수이기 때문이다.
func printScore() async {
let score = 1
Task { print(score) }
Task { print(score) }
}
즉, 위 코드를 보면 Task에 의해 캡쳐되고 있는 score는 let으로 정의된 상수이기 때문에 @Sendable을 사용할 수 있다. 만약 score가 var로 정의되어 값을 언제든 변경할 수 있다면 한 Task가 값을 변경하는 동안 다른 Task가 접근할 수 있기 때문에 변수로 정의되는 것은 허용되지 않는다.
func runLater(_ function: @escaping @Sendable () -> Void) -> Void {
DispatchQueue.global().asyncAfter(deadline: .now() + 3, execute: function)
함수나 클로저에 @Sendable을 붙이고 함수를 전달인자로 호출할 수 있다. runLater(printScore())로 호출하면 3초 뒤에 score가 출력될 것이다.
이제 SwiftUI에서 선택적으로 view에 modifier를 추가할 수 있는 것 같네요. 코드로 이해하는게 빠를 것 같다.
아시다시피 #if를 붙여 조건에 맞게 컴파일되게끔 했었다.
Text("Welcome")
#if os(iOS)
.font(.largeTitle)
#else
.font(.headline)
#endif
이제는 nested도 가능하고 다른 postfix 표현도 가능해졌다고 한다. 하지만 ' . '으로 postifx 표현이 되지 않는 경우 (예를 들면, result+[4] 의 경우)는 할 수 없다.
#if os(iOS)
.font(.largeTitle)
#if DEBUG
.foregroundColor(.red)
#endif
#else
.font(.headline)
#endif
let result = [1, 2, 3]
#if os(iOS)
.count // 3
#else
.reduce(0, +) // 6
#endif
print(result)
이제는 Swift가 CGFloat과 Double을 알아서 변환해준다고 한다!
let first: CGFloat = 42
let second: Double = 19
let result = first + second
print(result)
Swift는 필요한 경우 내재되어있는 생성자를 삽입하므로써 실행하며, 가능하다면 Double 형을 선호한다. 이미 있는 API들을 수정하여 하는 것이 아니라고 하는데(??) 예를 들면 SwiftUI의 scaleEffect()는 여전히 CGFloat으로 실행되지만 Swift는 조용히 Double과 연결시킨다.
Codable의 지원범위를 넓히는 업그레이드를 했다는데, 연관 값(associated value)을 가진 enum을 쓸 때 유용한 것 같다. 이전에 enum은 오직 RawRepresentable(raw value를 가지는)를 따를 때에만 지원되었는데, 이제는 general enum과 Codable한 연관 값(associated value)을 가진 case도 지원한다.
enum Weather: Codable {
case sun
case wind(speed: Int)
case rain(amount: Int, chance: Int)
}
case sun은 단순한 case이고, case wind(speed: Int)는 한 개의 연관값(associated value)을 가지고, case rain(amount: Int, chance: Int)는 두 개의 연관 값을 가지고 있다. 여기서 연관 값의 타입은 모두 Int 형이지만, 문자열이나 Codable 타입도 사용할 수 있다.
사용할 때 Weather 배열을 만들고 JSONEncoder나 유사한 것을 이용하고 printalbe string으로 결과를 변환하면 된다. 여러 개의 CodingKey enums를 사용할 수 있다.
let forecast: [Weather] = [
.sun,
.wind(speed: 10),
.sun,
.rain(amount: 5, chance: 50)
]
do {
let result = try JSONEncoder().encode(forecast)
let jsonString = String(decoding: result, as: UTF8.self)
print(jsonString)
} catch {
print("Encoding error: \(error.localizedDescription)")
}
다음 포스팅이 아마 마지막일 것 같다..
(출처: https://www.hackingwithswift.com/articles/233/whats-new-in-swift-5-5)