Xcode 8 GM 으로 겪어보는 Swift 3 의 변화들 #2
Xcode 8이 드디어 베타 딱지를 떼고 GM 마크를 박고 올라왔다. 이제 기능 면에서 바뀔 일은 없을 것 같으니 마지막으로 마무리 하는 겸으로 무엇이 바뀌었는지에 대한 경험담을 이어서 적어본다.
이 글은 'Xcode 8 Beta 로 겪어보는 Swift 3 의 변화들' 글에서 정리한 내용을 제외하고 GM 버전에서 추가로 발견한 사항들을 정리한다.
즉, 이제 NSDictionary 인스턴스에 오브젝트 타입 대신 구조체 값(Value)을 넣는게 가능해졌다.
예를 들어 특정 NSNumber 오브젝트의 64비트 정수형을 얻기 위한 getter 인 longLongValue 대신 Swift 3 에서는 int64Value 형식으로 접근하도록 바뀌었다.
또한 앞서 이야기한 NSDicionary 와의 호환성 향상에서 이야기 했다싶이 Any 타입을 사전형에서 사용할 수 있게 됨으로써 숫자 데이터를 형변환으로 가져올 수 있게 되었다. 무슨 말인지 모르겠으면 아래 예제를 보자. 우선은 Objective-C 코드이다.
Swift 에서 위 사전형 데이터에 엑세스 하려는 경우 예전에는 'value' 키에 지정된 값을 가져올 때 NSNumber 형식으로 가져온 뒤 여기서 intValue 를 호출해서 값을 가져와야 했다.
물론 반환값이 없는 경우는 제외지만 말이다.
만약 반환값이 필요없는 경우라면 아래와 같은 식으로 경고를 무시하는 방법이 있긴 있다.
Swift 3 에선 위 코드를 아래처럼 고쳐야 한다.
반대로 클로져가 다른 변수로 전달되는게 아니라 해당 메소드 내에서 호출되고 마는 경우라면 별도의 escaping 에 대한 속성은 필요없다. 앞서 이야기 했지만 기본적으로 @noescape 가 기본 속성이기 때문이다.
[이전글] Xcode 8 Beta 로 겪어보는 Swift 3 의 변화들
[관련글] Swift - @noescape 너 정체가 뭐냐
[관련글] 스위프트(Swift) 가이드
이 글은 'Xcode 8 Beta 로 겪어보는 Swift 3 의 변화들' 글에서 정리한 내용을 제외하고 GM 버전에서 추가로 발견한 사항들을 정리한다.
이 글을 올리는 오늘 Xcode 8 이 정식 릴리즈 되었다는 것은 참 거시기하다
Access Control 이 뒤엎어졌다
기존에는 public, internal, private의 세 가지 지시어가 있었는데 이게 아래와 같이 늘었고 의미 또한 바뀌었다.- public: 기존과 비슷하게 내외부 가리지 않고 접근 가능 이라는 의미이다. 대신 오버라이드를 할 수 없게 바뀌었다. 즉 Swift 2.x 버전의 public final 의 의미와 동일하다.
- open: 이전의 public 의 기능은 open 이라는 키워드로 옮겨왔다. 제한 없이 공개도 되고 오버라이드 제한도 없는 녀석이다.
- internal: 이전과 동일한 듯 하다.
- private: 소속된 네임스페이스 내에서만 접근이 가능한 것으로 바뀌었다. 이제 같은 파일이라도 private 로 선언된 클래스나 메소드 등에는 그 외부에서 접근 할 수 없다.
- fileprivate: 이건 기존의 private 와 비슷하게 동일 파일 내에서는 액세스가 가능하게, 그 외에는 접근 할 수 없게 만들어준다.
NSDicionary 호환성
기존의 Objective-C 에서 선언된 NSDictionary 타입은 [AnyObject : AnyObject] 타입이었다. 그래서 Swift 에서 이 NSDictionary 오브젝트에는 구조체(struct)타입의 데이터를 사용 할 수 없는 문제가 있었다.AnyObject 는 이름처럼 Object 즉 클래스 인스턴스만을 가리키는 타입이다.그런데 이제 NSDictionary 의 Swift 인터페이스는 별 다른 Generics 를 지정하지 않을 경우 기본적으로 [AnyHashable : Any] 타입으로 컨버전 된다.
즉, 이제 NSDictionary 인스턴스에 오브젝트 타입 대신 구조체 값(Value)을 넣는게 가능해졌다.
Swift 친화적인 NSNumber
이전에도 Foundation 의 Swift 친화에 대해 이야기 했었는데, NSNumber 도 Swift 타입에 어울리게 바뀌고 있다.예를 들어 특정 NSNumber 오브젝트의 64비트 정수형을 얻기 위한 getter 인 longLongValue 대신 Swift 3 에서는 int64Value 형식으로 접근하도록 바뀌었다.
또한 앞서 이야기한 NSDicionary 와의 호환성 향상에서 이야기 했다싶이 Any 타입을 사전형에서 사용할 수 있게 됨으로써 숫자 데이터를 형변환으로 가져올 수 있게 되었다. 무슨 말인지 모르겠으면 아래 예제를 보자. 우선은 Objective-C 코드이다.
// Objective-C Code NSDictionary *someDict = @{ @"value": [NSNumber numberWithInt: 10] };Objective-C 에선 일반 수치 데이터의 경우 객체가 아니기 때문에 포인팅이 불가능하기 때문에 NSNumber 오브젝트로 만들어서 사전형 데이터로써 사용했었다.
Swift 에서 위 사전형 데이터에 엑세스 하려는 경우 예전에는 'value' 키에 지정된 값을 가져올 때 NSNumber 형식으로 가져온 뒤 여기서 intValue 를 호출해서 값을 가져와야 했다.
// Swift 2.x (Xcode 7.x) let value = (someDict["value"] as! NSNumber).intValueSwift 3 에서는 아래와 같이 가져올 수 있다.
// Swift 3 (Xcode 8) let value = someDict["value"] as! Int한마디로 Swift 스러워졌다.
안쓰면 무조건 귀찮게 할거야!
기존에도 변수 등을 선언해 놓고 안쓰면 경고가 나왔는데, 이제는 더 귀찮게 한다. 함수의 반환값을 받아서 처리하지 않으면 무조건 경고를 낸다. @warn_unused_result 가 기본이 된 셈이다.물론 반환값이 없는 경우는 제외지만 말이다.
만약 반환값이 필요없는 경우라면 아래와 같은 식으로 경고를 무시하는 방법이 있긴 있다.
_ = someFunc()
이제 let 은 각각이 let 이어야... 뭐?
그냥 아래 코드를 보자.guard let a = someA, b = someB else { return }someA, someB 라는 옵셔널 변수의 값이 nil이 아니어야 guard 문을 통과할 수 있는 코드다.
Swift 3 에선 위 코드를 아래처럼 고쳐야 한다.
guard let a = someA, let b = someB else { return }뭐가 바꼈는지 알 수 있을 것이다. let 을 모두 붙여줘야 한다. 개인적으론 이런 스타일이 마음에 든다.
클로져는 기본적으로 도망(?) 칠 수 없어
함수나 메소드 등의 변수로 쓰이는 클로져는 이전과는 반대로 @noescape 속성이 기본적으로 붙게 되었다. 아래 코드를 보자.func someWork(completed: () -> ()) { ... DispatchQueue.global().async { ... DispatchQueue.main.async { ... completed() } } }평범한(?) GCD Dispatch Queue 를 활용해 비동기로 실행하는 유명한 예이다. 그런데 Swift 3 에서 이런 식의 코드는 Closure use of non-escaping parameter 'closureName' may allow it to escape 라는 형식의 오류가 발생한다. 따라서 아래처럼 해당 클로져의 escape 속성을 명확하게 해 주어야 한다.
func someWork(completed: @escaping () -> ()) { ... }@escaping 속성은 '이 클로져가 어딘가 저장되거나 나중에 호출 될 수 있게 메소드 등에 전달되는 용도로 사용될 수 있다' 라는 의미로 보자. 위의 경우는 디스패치 큐를 통해서 다른 스레드에서 별도로 클로져가 실행되는 환경이기에 escaping 이 필요하다.
반대로 클로져가 다른 변수로 전달되는게 아니라 해당 메소드 내에서 호출되고 마는 경우라면 별도의 escaping 에 대한 속성은 필요없다. 앞서 이야기 했지만 기본적으로 @noescape 가 기본 속성이기 때문이다.
[이전글] Xcode 8 Beta 로 겪어보는 Swift 3 의 변화들
[관련글] Swift - @noescape 너 정체가 뭐냐
[관련글] 스위프트(Swift) 가이드
댓글
매번 볼때마다 지식의 깊이에 감탄합니다.
항상 잘 보고 있습니다. :)
잘 읽고 갑니다~!