티스토리 뷰

Swift

Swift 5.4 Released!

Zedd0202 2021. 4. 28. 22:06
반응형

 

안녕하세요 :) Zedd입니다.

4월 26일에 Swift 5.4가 릴리즈 됐네요.

Xcode 12.5 Beta Release Notes 📝의 Swift > New feature부분에서 다루긴 했는데,

안본것도 있고 그러니 호다닥 공부해보겠습니다.

 

Swift 5.4는 다음과 같은 새로운 언어 feature가 포함됩니다.

- functions, subscripts, initializers에서 multiple variadic parameters 지원.

- implicit member syntax확장 

- Result builders 

- overloading을 지원하는 Local functions(지역 함수) 

- local variables(지역 변수)에 대한 Property wrappers

 

# [SE-0284] functions, subscripts, initializers에서 multiple variadic parameters 지원.

func foo(_ a: Int..., b: Double...) { }

struct Bar {
  subscript(a: Int..., b b: Int...) -> [Int] { a + b }

  init(a: String..., b: Float...) { }
}

원래

single variadic parameter만 가능했고, 한개 이상하려고 하면 위와같은 오류가 났는데 

Swift 5.4에서는 레이블만 달려있으면

1개 이상의 variadic parameter가 가능하다.

 

# [SE-0287] implicit member syntax확장 

Swift 5.4에서는 다음 코드가 유효한것으로 판단.

let milky: UIColor = .white.withAlphaComponent(0.5)
let milky2: UIColor = .init(named: "white")!.withAlphaComponent(0.5)
let milkyChance: UIColor? = .init(named: "white")?.withAlphaComponent(0.5)

SwiftUI의 경우

Text("Hello, world!")
            .foregroundColor(.red.opacity(0.5))

이런게 가능해지는 것.

원래

Text("Hello, world!")
            .foregroundColor(Color.red.opacity(0.5))

이렇게 Color라고 꼭 써줘야됐음.

+ Swift 5.4이전에서도 당연히

Text("Hello, world!")
            .foregroundColor(.red)

이거는 된다. 체이닝이 안됐던 것 뿐.

 

# [SE-0289] Result builder

이건 잘 이해가 안가니 나중에 따로 글을...

 

# [SR-10069] overloading을 지원하는 Local functions(지역 함수) 

💡 overloading(오버로딩) : 같은 이름의 메서드 여러개를 가지면서 매개변수의 타입과 개수가 다르도록 하는 기술

ƒ라는 함수 안에서 nested라는 이름을 가진 지역 함수 2개를 작성.

이름은 같지만 파라미터 타입이 다르므로 오버로딩이 사용(?)되었다고 할 수 있다. 

Swift 5.4이전 - 컴파일에러

Swift 5.4이후 - OK!

 

# local variables(지역 변수)에 대한 Property wrappers

Property wrapper에 대한 내용은 Property Wrapper 글 참고.

(위 글에 대한 예제를 그대로 사용하겠음)

@propertyWrapper
struct Uppercase {
    
    private var value: String = ""
    
    var wrappedValue: String {
        get { self.value }
        set { self.value = newValue.uppercased() }
    }
    
    init(wrappedValue initialValue: String) {
        self.wrappedValue = initialValue
    }
}

이런 로직들을 Property wrapper로 만들고,

struct Address {
    @Uppercase var town: String
}

이런식으로 사용이 가능했음.

하지만

func f() {
    @Uppercase let town: String
}

이렇게 지역변수로 Property wrapper를 만들면

local variables은 아직 Property wrapper를 지원안한다고 컴파일에러.

Swift 5.4부터는 이것도 가능

 

# Runtime Performance and Code Size Improvements

1. Swift 5.4에서는 previous lookup 결과를 캐싱하기 위해 더 빠른 Hash Table구현

→ 프로토콜 적합성 검사가 훨씬 빨라짐

→ 공통 런타임 as? 과 as! casting operations 속도가 높아짐 

 

2. 연속적인(consecutive) Array 수정은 중복된 고유성 검사를 방지한다.

func foo(_ a: inout [Int]) {
  // copy-on-write (CoW) 체크를 여기서 반드시 한다. 
  a[0] = 1
  // 컴파일러는 여기서 중복 COW검사를 생성하지 않음. 
  a[1] = 2
}

 

3. 다양한 성능 향상

- 문자열 보간(String interpolations)은 보다 적극적으로 일정하게 접힌다..? (more aggressively constant-folded)

- inout 함수 argument 및 루프 내에서 retain/release 호출 감소

- 표준 라이브러리의 일반 메타 데이터는 이제 컴파일 타임에 specialize되어 dirty memory사용량을 줄이고 성능을 향상시킨다.

 

# Build Performance

1. Swift 컴파일러는 파일간의 종속성을 추적하는데 훨씬 더 뛰어나졌음

→ 증분 빌드 중에 여러 종류의 변경사항에 대해 컴파일 된 파일 수가 크게 감소.

 

2. 이제 멤버 변수 및 구조체, 열거형, 클래스 및 프로토콜의 함수에 대한 종속성은 Swift 컴파일러에 의해 개별적으로 추적됨 

→ 이러한 엔티티 변경 후 rebuilds 속도가 빨라지고 축소된다? (shrinks)

 

3. 증분 빌드는 더 많은 경우에 deterministic products를 생산한다..(Incremental builds produce deterministic products in many more cases. 이건 뭔소린지 모르겠음)

 

# Code Completion

- Code Completion의 성능은 큰 함수 본문(large function bodies)에서 훨씬 빨라졌음.

swift-package-manager repository 한 예제에서 self. 에 대한 Code Completion은 Swift 5.3에 비해 4배 빨라짐(20ms → 4ms) 

- Code Completion은 오류가 포함된 expressions과 추가 context가 없는 모호한(ambiguous) 식에서도 더욱 안정적이 됨.

func test(a: Int, b: String) -> Int { ... }
func test(a: Int, b: Int) -> String { ... }
func test(a: (Int, Int) -> Int) -> Int { ... }

위 코드의 경우 

test().prefix(3). 후 code completion은 String멤버를 제안.

test(a: 2).  후 code completion은 Int 및 String 멤버를 제안.

test { $0. } 후 $0. code completion은 블록에서 Int멤버를 제안.

 

# Type Checker

1. Swift 5.4는 a + b + (2 *c)와 같은 "연결된" expressions에 대한 타입 검사 성능을 향상.

ex. 

struct S { var s: String? }

func test(_ a: [S]) {
   _ = a.reduce("") {
     ($0 + "," + ($1.s ?? "")) + ($1.s ?? "") + ($1.s ?? "")
   }
}

위 코드의 경우 원래는 시간 초과가 떴지만, 

(이렇게)

Swift 5.4컴파일러에서는 100ms이내에 완료된다고 함.

 

2. Type Checker는 다른 리터럴 표현식을 포함하는 중첩된 배열 리터럴에 대한 성능을 개선.

ex.

enum E {
  case first
  case second
  case third
}

let dictionary = [
  .first: [0, 1, 2, 3, 4, 5, 6, 7],
  .second: [8, 9, 10, 11, 12, 13, 14, 15],
  .third: [16, 17, 18, 19, 20, 21, 22, 23],
]

위 코드의 경우에는 사실 컴파일에러가 떠야함. 왜냐? enum E에 대한 추론을 할 수 없기 때문

하지만 그런 에러는 안뜨고 “too complex to solve in reasonable time”라는 메세지가 뜬다. 

(이렇게)

Swift 5.4에서는 정확한 오류메세지와 함께 코드를 유효하지 않은 것으로 진단함.

error: reference to member 'first' cannot be resolved without a contextual type
.first : [ 0, 1, 2, 3, 4, 5, 6, 7],
 ^
error: reference to member 'second' cannot be resolved without a contextual type
 .second : [ 8, 9, 10, 11, 12, 13, 14, 15],
 ^
error: reference to member 'third' cannot be resolved without a contextual type
 .third : [16, 17, 18, 19, 20, 21, 22, 23],
 ^

 

3. Type checker가 잘못된 statements(e.g. invalid return statement), 잘못된 선언 참조 및 패턴 일치 오류를 포함하여 결과 빌더에 대한 진단 개선

import SwiftUI

struct ContentView: View {
  @State private var condition = false

  var body: some View {
    Group {
      if condition {
        Text("Hello, World!")
          .frame(width: 300)
      } else {
        return Text("Hello, World!")
      }
    }
  }
}

위 코드의 경우 

이런 에러가 떴지만, Swift 5.4 컴파일러에서는

error: cannot use explicit 'return' statement in the body of result builder 'SceneBuilder'
 return Text("Hello, World!")

정확한 오류를 보고하게 됨.

 

# Debugging

Apple 플랫폼에서 Swift 코드를 디버깅 할 때 resilient type(탄력적인 타입. URL, URLComponents, Notification, IndexPath, Decimal, Data, Date, Global, Measurement, UUID를 포함한 Foundation value types)을 가진 변수가 Xcode variable view 와 frame variable에 표시됨. 

 

 

참고

swift.org/blog/swift-5-4-released/

반응형

'Swift' 카테고리의 다른 글

Swift 5.5 ) Codable synthesis for enums with associated values  (0) 2021.11.18
WWDC 21 ) What‘s new in Swift  (3) 2021.06.11
Swift 5.4 Released!  (3) 2021.04.28
Introducing Swift Collections  (0) 2021.04.13
dynamicCallable  (0) 2021.03.18
dynamicMemberLookup  (0) 2021.03.11
댓글
  • 프로필사진 우주미아홍구 감사합니다.

    저는 바.보입니다.
    2021.04.30 14:13
  • 프로필사진 nick 안녕하세요 원티드 특강 때 뵙고 질문을 드리고 싶은 것이 있어 이렇게 블로그로 방문하게 되었습니다 ㅎㅎ
    저는 리액트 네이티브로 쇼핑몰 어플.(지그재그나 에이블리 같은) 을 만들었는데요, 리네의 기술적 한계로 인해 swift로 iOS 어플을 개발하려고 합니다

    zedd님께 무엇을, 어떤 순서로 배워야 할지에 대해 여쭙고 싶습니다 !

    swift 언어로 iOS 어플을 만들 수 있는 것은 검색을 통해 알게되었습니다. 또, 강좌나 책 같은 것을 찾아보니 ‘storyboard’, ‘swiftUI’ 가 있더라구요.
    스토리보드는 역사가 깊어서 자료가 많고, 스위프트는 애플에서 권장하고 있는 방식이고 앞으로 더 비중이 높아지지만 자료가 아직은 많지는 않다, 라고 검색을 통해 알게 되었습니다
    ( 이제 검색한지 2일차라 정확한지는 모르겠네요 ㅠ )

    현재는 고려하고 있는 사항이 ‘스토리보드 vs 스위프트ui’ 이지만, 입문자에게 도움이 될 만한 내용이 있다면, 혹시 알려주실 수 있으실까요??
    어떤 키워드로 구글링을 해야 할지도 몰라 막막한 지금입니다..ㅋㅋㅋ
    답변 주시면 정말 감사하겠습니다 ^^
    2021.05.12 16:02
  • 프로필사진 Favicon of https://zeddios.tistory.com BlogIcon Zedd0202 스토리보드 vs 스유 비교는 잘 안맞는 것 같아요~
    굳이 비교하자면 UIKit vs 스유인데..스유는 스유2가 되어서야 아주 아주 그나마 사용할 수 있는 정도가 되었습니다. 스유를 사용하신다고 해도 스유가 지원하지 않는 뷰를 만드려면 UIKit을 사용하셔야합니다.

    그래서 일단은 UIKit으로 먼저 개발해보시는 것을 추천드립니다~
    2021.05.12 23:10 신고
댓글쓰기 폼
반응형
Total
4,016,118
Today
610
Yesterday
2,463