Swifter {Swift Developer}

메뉴

Xcode 8 Release Notes 주요 내용 정리

Xcode 8 Release Notes에서 Swift 관련된 내용만 정리한 것이다. 대부분의 개발자들은 Release Notes를 안읽어보는 경향이 있어 나름대로 중요하다고 생각되는 부분들을 정리해 보았다.

원문: https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html

개발환경

  • Xcode 8 (8A218a)
  • iOS 10.0.2
  • Swift 3.0

Release Notes

[25680392] Swift 2.3과 Swift 2.2는 비슷하지만 다르다.

Xcode8에서 사용하는 Swift 2(2.3)은 Xcode 7.3.1의 Swift 2와 비슷하다. 하지만 이는 새로운 SDK를 위해 업데이트되었다. Xcode 7.3.1에서 컴파일된 프레임웍과의 호환성은 없다.

마이그레이션

Swift 2에서 Swift 3으로의 마이그레이션 내용은 Swift Migration Guide를 참조하자.

Swift.org – Migrating to Swift 2.3 or Swift 3 from Swift 2.2 

[26919123] 오류메시지가 상세히 나오게 되었다.

Swift 프로그램이 실행될 때 null예외에 그쳤던 오류메시지에 “!”또는 암시적 공개선택적 형이 사용되고 있는 소스코드의 위치를 보고하도록 되었다.

(SE-0111) 함수 형의 일부로 함수의 인수 레이블을 고려한 사양을 폐지하여 타입시스템을 간단하게

Swift함수 형으로부터 인수 레이블을 제거한다. 대신 함수명이나 서브스크립트 및 이니셜라이저명의 일부가 된다. 함수 및 서브스크립트와 이니셜라이저를 호출시 지금처럼 인수 레이블이 필요하다.

그러나 함수 및 이니셜라이저에 대한 참조는 인수 레이블을 사용하지 않는다.

참고로 명시적으로 작성된 함수형도 인수 레이블을 사용하지 않는다. 그럼에도 불구하고 문서화를 위해 인수 레이블을 사용하고 싶다면 인수 레이블 위치에 “_”을 사용한다.

swift-evolution : 0111-remove-arg-label-type-significance

(SE-0116) Objective-C의 ID가 Swift에서 AnyObject로 되던 것을 Any로 변경

Objective-C의 API로 id를 사용하던 부분이 Swift는 AnyObject에서 Any로 변경되었다. 마찬가지로 형지정이 되지 않았던 NSArray와 NSDictionary는 Swift에서 [Any]또는 [AnyHashable: Any]로 되었다.

swift-evelution : 0116-id-as-any

[27853737] IBAction의 sender

IBAction의 sender에 Any를 지정할 수 있게 되었다.

[27639935]

Objective-C의 ID로 Swift는 AnyObject 대신 Any를 사용할 수 있기 때문에 AnyObject에서 동적조회를 사용하던 부분의 오류가 발생할 수 있다.

예를 들면 이런 형태이다.

수정하면 동적 조회 앞에 AnyObject를 캐스팅하거나 원하는 형으로 캐스팅한다.

(SE-0103) @noescape 기본동작하게 되었다.

클로저 인수는 @noescape로 기본동작하게 되었다. @escaping을 사용하여 클로저가 나올 수 있게 되었다.

@autoclosure(escaping)이라고 작성하던 부분은 @autoclosure @escaping이라고 작성하게 되었다. 주석으로 @noescape와 @autoclosure(escaping)은 폐지되었다.

swift-evolution: 0103-make-noescape-default

(SE-0102) @noreturn 속성이 폐지되고 열거형 Never를 리턴값으로 지정하게 되었다.

호출자에게 제어를 리턴하지 않을 경우 @noreturn특성이 폐지되었다. 대신 Never를 리턴형으로 지정한다.

[15101588] Objective-C프로토콜형이 된 클래스가 Swift은 프로토콜형의 값이 된다?

Objective-C에서 프로토콜형이 되는 클래스를 Swift는 프로토콜형의 값을 가져온다. 예로 Class가 NSCoding.Type이다.

(SE-0055) null이 될 수 있는 UnsafePointer는 선택적으로 사용할 수 있게 되었다.

UnsafePointer, UnsafeMutablePointer, AutoreleasingUnsafeMutablePointer, OpaquePointer, Selector, NSZone등의 형은 보통 형이 되었다. 이들은 결코 nil이 될 수 없다.

null이 될 수 있는 포인터는 Swift에서는 선택적 형이 되었다. 예로 UnsafePointer?라는 형태이다.

C언어에서 가져온 객체 이외의 형(Int *등)도 고려했다.

  • _Nonnull과 NS_ASSUME_NONNULL_BEGIN/_END블록으로 지정된 포인터는 일반적인 포인트형이다. 예로 “NSInteger * _Nonnull”은 UnsafeMutablePointer이다.
  • _Nullable이 지정되어 있는 포인터는 선택적 형이다. 예로 “NSInteger * _Nullable”은 UnsafeMutablePointer?이다.
  • Null_unspecified가 지정되어 있거나 NS_ASSUME_NONNULL_BEGIN/_END블록 외부의 지정이 없는 포인터는 암시적으로 공개된 선택적 형이다. 예로 “NSInteger * _Null unspecified”는 UnsafeMutablePointer!”이다.

이는 Swift표준 라이브러리와 일치하도록 조절되어 있다. C의 가변인수를 취하는 함수에 null이 될 수 있는 포인터를 전달하기 어렵기 때문에 Swift는 이를 직접적으로 허용하지 않는다. 이 문제를 해결하기 위해 다음과 같이 포인터와 같은 크기의 정수값을 리턴한다.

가져온 포인터가 지시하는 형은 주석이 붙어 있어도 항상 Nullable이라고 상정하지 않는다. 그러나 임사적 또는 명시적으로 Null_unspecified를 지정한 경우 선택적 형을 가져온다.

swift-evolution : 0055-optional unsage-pointers

[16888940] Core Foundation형명에서 끝에 Ref를 삭제했다.

Core Foundation의 형명 끝에 Ref를 삭제했다. CFStringRef의 경우 CFString이다. 그러나 Ref기능과 Ref없이 모두 사용되는 경우에는 예외로  Ref있는 그대로 가져온다.

(SE-0099) 조건절에서 표준구문을 사용하게 되었다

if, guard, while 조건문의 형을 표준구문으로 사용할 수 있게 변경되었다. 각각의 패턴 및 선택적 바인딩에 case 또는 let을 붙일 수 있고 구문은 모두 “,”이다.

이전까지는

새로운 작성형태는

swift-evolution : 0099-conditionclauses

[22051279] 중첩된 제네릭 함수가 주변환경을 캡쳐할 수 있게 되었다.

(SE-0046) 함수 인수는 모든 인수로 분류되게 되었다.

함수 인수는 모든 인수로 분류되게 되었다. 이 변경으로 첫번째 인수도 두번째 인수처럼 행동할 수 있게 되었다.

이전까지는

새로운 작성형태는

swift-evolution : 0046-first-label

(SE-0064) Objective-C의 getter와 setter에 대한 선택기 #selector에서 사용할 수 있게 되었다.

swift-evolution : 0064-property-selectors

컬렉션의 서브타입 변환과 동적캐스트 프로토콜에서 실행되도록 되었다.

(SR-2131) 빈문자열이 모든 문자열의 접두사, 접미사와 일치하게 되었다.

hasPrefix, hasSuffix함수에 빈문자열을 전달할 때 모든 문자열의 접두사, 접미사와 일치하게 되었다.

NS_OPTIONS의 None은 사용못하게 되었다.

NS_OPTIONS의 None을 가져올 때 사용불가로 나온다. None대신 “[]”을 사용하면 빈옵션셋트를 만들 수 있다.

typealiases에서 제네릭을 사용할 수 있게 되었다.

 

@noescape는 보다 일반적인 속성으로 확장되었다.

@noescpae는 보다 일반적인 속성으로 확장되었다. @noescape함수의 값을 선언할 수 있다. 또한 로컬변수를 @noescape형으로 하거나 typealiases에서 @noescape를 사용할 수 있다.

함수의 커리에 대한 구문은 삭제되었다.

제네릭으로 지정할 수 있는 요소로서 슈퍼클래스를 지정할 수 있게 되었다.

rethrows로 지정된 함수에 catch블록안에서 예외를 발생시킬 수 있게 되었다.

rethows로 지정된 함수에서 예외를 던질 수 있는 선택적인 클로저를 실행할 수 있게 되었다.

(SE-0067) FloatingPoint를 확장하여 IEEE754에 필요한 작업을 만족할 수 있도록 수정되었다.

FloatingPoint를 확장하여 IEEE754에 필요한 작업을 총족하도록 수정했다. 또한 몇가지 유용한 속성이 추가되었다. 대부분이 추가되었지만 기존코드에 영향을 미치는 변경이 4가지 있다.

  • FloatingPoint형의 %는 비활성화되었다. formTruncatingRemainder(dividingBy:)대신에 사용할 수 있다.
  • “.NaN”은 “.nan”으로 변경되었다.
  • “.quietNaN”은 삭제되었다. 대신 “.nan”을 사용한다.
  • “isSignaling”은 isSignalingNaN”으로 변경되었다.

swift-evolution: 0067-floating-point-protocols

(SE-0071) 대부분의 키워드가 구성원으로 사용할 수 있게 되었다.

일일이 “`”을 앞뒤로 둘러쌀 필요없이 사용할 수 있다.

swift-evolution : 0071-member-keywords

(SE-0062) 키경로지정에 #keyPath를 사용할 수 있게 되었다.

swift-evolution : 0062-objc-keypaths

(SE-0031) inout이 “:”뒤에 붙는다.

이전까지는

새로운 작성형태는

swift-evolution : 0031-adjusting-inout-declarations

(SE-0034) #line이 #sourceLocation이 되었다.

swift-evolution: 0034-disambiguating-line

(SE-0025) private으로 표시된 선언은 그 범위내에서만 사용할 수 있게 되었다.

원래 private는 fileprivate에 있다.

swift-evolution : 0025-scoped-access-level

(SE-0036) 열거형 요소는 “.”가 필요하다.

열거형 요소에 인스턴스 멤버에서 접근한 경우 현재는 컴파일오류가 발생한다.

swift-evolution: 0036-enum-dot

(SE-0043) case절에서 여러가지 패턴으로 변수를 선언할 수 있게 되었다.

swift-evolution : 0043-declare-variables-in-case-labels-with-multiple-patterns

[17960407] 상위클래스와 파생클래스가 제네릭도 초기화가 상속된다.

(SE-0081) where절은 서명후 본문앞에 쓰게되었다.

이전까지는

새로운 작성은

swift-evolution: 0081-move-where-expression

(SE-0129) NSError는 Error로 브릿지되었다.

Objective-C의 NSError는 Swift는 Error프로토콜로 브릿지된다. NSString이 String으로 브릿지된 것과 같은 느낌이다.

UIApplicationDelegate의 application(_:didFailToRegisterForRemoteNotificationsWithError:)라는 느낌이다.

이 경우 인수가 Error이다.

또한, Cocoa와 Cocoa Touch에서 가져온 오류형은 모든 정보를 가지고 있기 때문에 NSError로 잡을 필요가 없다.

예로 사용자정보를 얻으려면 이런 형태이다.

Swift에서 정의된 오류형은 새로운 LocalizedError프로토콜을 사용하여 지역화된 설명을 제공할 수 있다.

마찬가지로 새 RecoverableError와 CustomNSError프로토콜을 사용하는 것으로 새로운 제어를 할 수있다.

swift-evolution : 0112-nserror-bridging

(SE-0095) 프로토콜 합성이 변경되었다

“protocol <…>”형이 없어지고 대신 ‘&’을 사용하게 되었다.

이전에는 프로토콜 합성은 protocol <>을 사용했다. 이것도 삭제되고 Any를 사용하게 되었다.

swift-evolution : 0095-any-as-exstential

(SE-0072) 암시적 브릿지 변환은 없어졌다

Swift값 형에서 지원하는 Objective-C객체로 변환하는 경우 as를 사용한다. 예를 들어 string as NSString이라는 형태를 말한다. 또한 Swift에서 값은 as AnyObject로 해서 id를 박스화할 수 있다.

Swift-evolution : 0072-eliminate-implicit-bridging-conversions

(SE-0040) 특성의 인수지정은 ‘=’ 대신 ‘:’을 사용하게 되었다.

swift-evolution: 0040-attributecolons

(SE-0096)

dynamicType은 삭제되었다. 대신 “type (of:)”함수가 추가되었다. 기존코드에서 “.dynamicType”을 사용한다면 새로 작성해야 한다. sizeof도 같이 .dynamicType을 사용하는 코드는 SE-0101에서 도입된 MemoryLayout사용형태로 변경해야 한다.

swift-evolution: 0096-dynamictype

(SE-0077) 연산자 선언이 향상되었다.

새 연산자를 추가하는 구문이 크게 변경되었다. 새 모델은 매직넘버를 사용하는 것이 아니라 우선 그룹을 바탕으로 하게도록 변경되었다. 이는 새 연산자의 선언에만 적용하여 기존 연산자 오버로드는 추가하지 않는다.

swift-evolution: 0077-operator-precedence

(SE-0060) 기본값을 가지는 인수는 선언순서로 지정해야 한다.

기본값을 가지는 인수는 선언순서로 지정해야 한다. 함수를 호출하는 측은 항상 선언된 순서대로 인수를 지정한다.

기본값을 가지는 인수는 순서를 지키고 있으면 그만큼 절약이 가능하다.

swift-evolution: 0060-defaulted-parameter-order

(SE-0053) 불필요한 let은 삭제되었다

함수의 인수에서 let선언이 제거되었다.

컴파일 오류 형태

추천하는 형태

swift-evolution: 0053-remove-let-from-function-parameters

(SE-0003) 함수의 인수로 var는 사용할 수 없게 되었다

이전 형태

새로운 형태

swift-evolution: 0003-remove-var-parameters

(SE-0117) public 클래스는 모듈 외부에서 상속할 수 없게 되었다

public 클래스는 모듈 외부에서 상속할 수 없게 되었다. public 메소드는 모듈 외부에서 재정의할 수 없게 되었다. 이 말은 모듈 외부에서 상속하거나 재정의하는 경우 open을 선언하자. 이것이 public 이상의 새로운 접근수준으로 추가되었다.

Objective-C에서 가져온 클래스나 메소드는 public이 아니더라도 open된다. 단위테스트 @testable을 사용하는 경우 public에서도 상속과 재정의는 가능하다.

swift-evolution: 0117-non-public-subclassable-by-default

(SR-700) Swift에서 오류가 발생시, NSError의 domain속성은 모듈명이나 상수가 포함되어 있다.

(25759260) ‘init’로 이름이 시작되는 메소드는 Objective-C의 init메소드 멤버로 고려된다.

(SE-0093) 슬라이드형은 원래 컬렉션에 접근하기 위한 base속성이 있다

swift-evolution : 0093-slice-base

(26561852) 플레이그라운드에서 파일 리터럴은 NSURL대신 URL로 변경되었다

(SE-0136과 SE-0101) 메모리레이아웃 관계의 변경들

sizeof(), strideof(), alignof()함수가 삭제되었다. 대신 MemoryLayout.size, MemoryLayout.stride, MemoryLayout.alignment를 사용할 수 있다. sizeofValue(), strideofValue(), alignofValue()는 MemoryLayout.size(ofValue:), MemoryLayout.stride(ofValue:), MemoryLayout.alignment(ofValue:)로 변경되었다.

swift-evolution : 0101-standardizing-sizeof-naming

swift-evolution : 0136-memory-layout-of-values

(SE-0130) String의 이니셜라이저와 append가 사용하기 쉬워졌다

Character와 UnicodeScalar의 반족을 지정하는 String이니셜라이저와 String.append인수에서 형이 특정되게 되었다.

이전 형태

새로운 형태

이것도 이전 형태

새로운 형태

다른 방법

swift-evolution: 0130-string-initializers-cleanup

(SE-0125) 여러가지 참조를 확인하는 방법이 바뀌었다.

isUniquelyReferenced(), isUniquelyReferencedNonObjC()는 삭제되었고 대신 isKnownUniquelyReferenced()를 사용한다. isUniquelyReferenced()를 사용할 때 필요하던 NonObjectiveCBase도 삭제되었다.

ManagedBufferPointer.holdsUniqueReference는 ManagedBufferPointer.isUniqueReference로 변경되었다.

이전 형태

새로운 형태

swift-evolution : 0125-remove-nonobjectivecbase

(SE-0107) Unsafe [Mutable] RawPointer가 추가되었다

이는 Unsafe [Mutable] Pointer를 대체하는 것으로 UnsafePointer에서 UnsafePointer로 변환을 허용하지 않는다. Unsafe [Mutable] RawPointer는 형식화되지 않은 메모리 접근과 메모리에 타이핑을 제공한다. 형식화된 메모리는 안전하게 포인터형태로 변환할 수 있다. 자세한 내용은 bindMemory(to:capacity:), assumingMemoryBound(to:), withMemoryRebound(to:capacity:)를 살펴보기 바란다.

swift-evolution: 0107-unsaferawpointer

(SE-0128) UnicodeScalar의 이니셜라이저가 실패가 가능해졌다.

이전 형태

새로운 형태

swift-evolution: 0128-unicodescalar-failable-initializer

(SE-0127) 포인트 주위의 변경들

withUnsafePointer, withUnsafeMutablePointer함수에 “to:”인수가 추가되었다. 이 함수를 사용시 이 인수는 필수이다. withUnsafePointers, withUnsafeMutablePointers는 삭제되었다. 이 함수 대신 하나의 포인터를 사용하는 함수를 사용한다.

unsafeAddressOf함수는 삭제되고 대신 ObjectIdentifier(x).unsafeAddress를 사용한다.

ManagedProtoBuffer클래스는 삭제되었다. 형에 대한 명시적인 참조로 사용하는 클래스는 ManagedBuffer가 있다.

swift-evolution : 0127-clearing-up-stdlib-ptr-buffer

(SE-0131) 해시를 사용한 컬렉션 AnyHashable을 사용한다

표준 라이브러리에서 해시를 사용하기 위해 AnyHashable이 도입되었다. Objective-C의 NSDictionary나 NSSet을 가져올떄 [AnyHashable: Any] 및 Set이다.

swift-evolution: 0131-anyhashable

(SE-0124) Int와 UInt의 이니셜라이저가 변경되었다

Int.init(ObjectIdentifier)와 UInt.init(ObjectIdentifier)는 “bitPattern:”레이블이 필요했다. 해당 이니셜라이저는 ObjectIdentifier를 인수에서 얻는다.

이전 형태

새로운 형태

swift-evolution: 0124-bitpattern-label-for-int-initializer-objectidentifier

(SE-0109) Boolean프로토콜은 삭제되었다.

swift-evolution: 0109-remove-boolean

(SE-0113) FloatingPoint함수가 추가되었다.

이런 방법은 IEEE754 roundToIntegral에 연결된다. 마찬가지로 C/C++ round(), ceil(), floor(), trunc()에서 제공된다. 그외 fabs, sqrt, fma, remainder, fmod, ceil, floor, round, trunc가 FloatingPoint에서 사용할 수 있도록 진행중이다.

Swift-evolution: 0067-floating-point-protocols

swift-evolution: 0113-rounding-functions-on-floatingpoint

(SE-0091) 형과 확장에서 연산자를 정의할 수 있게 되었다.

이런 연산자를 static으로 선언하고 글로벌용과 동일한 서명을 가질 필요가 있다. 이로 인해 프로토콜로 선언한 연산자를 static으로 하기로 한다.

다만 SE-0091에 올려진 형 검사의 최적화는 아직 구현되어 있지 않다.

swift-evolution: 0091-improving-operators-in-protocols

(SE-0120) patition메소드 변경

컬렉션의 partition()과 partition(isOrderedBefore:)는 삭제되고 partition(by:)로 대체되었다.

이전 형태

새로운 형태

swift-evolution: 0120-revise-partition-method

(SE-0133) flatten이 joined되었다

Sequence.flatten()과 Collection.flatten()은 각각 Sequence.joined()와 Collection.joined()로 변경되었다.

Swift 2.3

Swift 3.0

swift-evolution: 0133-rename-flatten-to-joined

(22457329) 액티브 컴파일 조건

활성화된 컴파일 조건은 빌드설정을 Swift컴파일러에게 전달하는 새로운 설정이다. 이 설정은 각각의 요소는 “-D”와 같이 swiftc에 전달하여 전처리 매크로처럼 clang에 전달한다.

(24213154) Swift 컴파일 옵션 추가

Swift 컴파일러 옵션에 새로운 옵션이 2개 추가되었다.

  • -suppress-warnings (SWIFT_SUPPRESS_WARNINGS)
  • -warnings-as-errors (SWIFT_TREAT_WARNINGS_AS_ERRORS_
    이 설정들은 clang빌드설정옵션과는 무관하다.

(26158130) EMBEDDED_CONTENT_CONTAINS_SWIFT는 없어지고 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES가 추가되었다.

이 새로운 설정은 Xcode에서 항상 Swift Standard Libearies를 채워넣도록 지정하는 것이다. 대상에 직접 사용하거나 덧붙여 다른 제품이 Swift를 사용하는 경우에만 이 설정을 사용할 수 있다.

(20119003) 사전이나 배열의 플레이그라운드 리터럴 실행

암시적으로 브릿지변환이 삭제된 것으로 플레이그라운드의 배열과 사전 리터럴은 NSArray과 NSDictionary로 형검사를 하지 않기에 종종 의도하지 않게 실행된다. 그러나 명시적으로 “[] as NSArray”나 “[:] as NSDictionary”라고 선언하면 원하는 결괄르 얻을 수 있다.

 

Facebook Comments

카테고리:   Xcode

댓글

죄송하지만 댓글은 닫혀 있습니다.