ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Apple Dev Reference] Nullability and Objective-C
    앱등이에게 살충제를 뿌린다./Apple Dev Reference 2016. 5. 22. 18:04

    <아무 이유없이 할리퀸>



    Nullability and Objective-C

    글 하단에 3줄요약 해놓음



    Swift와 Objective-C를 한 프로젝트에서 같이 사용할 수 있다는 것.

     Swift의 장점 중 하나입니다.(이걸 장점이라고 해야하나 모르겠네요)


    하지만 Objective-C와 Swfit에는 명백히 많은 차이점이 존재합니다. 그 중 하나를 예로 들어보겠습니다. Swift에는 Optional타입과 non-Optional타입이 존재합니다. NSView와 NSView?같이 말이죠. 반면에, Objective-C에는 딱 하나 NSView *만 존재하고 있습니다. 이 차이점으로 인해 컴파일러는 혼돈이 생길 수 밖에 없습니다. NSView *가 Optional인지 non-Optional인지 알 도리가 없는거죠. 따라서 현재(Swift2.2 기준) 컴파일러는 NSView *Implicitly Unwrapped Optional 타입(NSView!)으로 인식하고 있습니다. 하지만 non-Optional을 Implicitly Unwrapped Optional로 인식하면 문제가 발생할 수 있기에 조치가 필요합니다.


    이전 버전에서는 Apple 프레임워크에 대해서만 Objective-C와 Swift간의 옵셔널 호환이 지원이 되었지만 XCode 6.3에서부터는 nullability annotations를 통해서 Custom 코드에서도 Optional에 대한 호환이 가능하도록 업데이트 되었습니다.



    _Nullable and _Nonnull

    nullability annotaion은 두 개의 annotation이 있습니다. _Nullable과 _Nonnull입니다. 예상하시겠지만 _Nullable타입은 nil을 갖을 수 있습니다. 하지만 _Nonnull은 절대로 nil이 되어선 안되는 값이죠. 이를 어길 경우 컴파일 단계에서 warning이 발생하게 됩니다.


    _Nullable과 _Nonnull키워드는 C의 const키워드를 사용할 수 있는 곳이라면 어디든 사용할 수 있습니다. 물론 포인터 타입과 함께 사용해야겠죠. 아래의 예제처럼 언더바 없이 소문자로 사용할 수도 있습니다. 보통은 메소드의 선언 부분에서 소괄호 내부 제일 앞쪽에 쓰는것이 좋습니다.


    프로퍼티의 경우에도 프로퍼티의 attribute리스트에 나열하여 사용할 수 있습니다.



    Audited Regions

    nullable annotation을 적용할 때, audited for nullability를 사용할 수 있습니다. 소스의 특정 부분을 MARK해두면 이 부분에서 nullable annotation을 사용하지 않은 포인터는 nonnull로  인식됩니다. 예제에서는 nullable만 지정해주고 nonnull은 지정해주고 있죠? 이를 이용하면 우리가 위에서 다룬 예제들의 소스가 훨씬 간결해집니다.


    이 방식에는 안정성을 위한 몇 가지 주의사항이 있습니다.

    • typedef으로 정의한 타입은 nullability속성을 상속받지 않습니다. 이 타입들은 따라서 컨텍스트에 따라 nullable이거나 non-nullable을 갖게 됩니다. 때문에 typedef타입은 nullabilty annotation 구역내에 있어도 자동으로 nonnull로 인식되지 않습니다.
    • id *와 같이 복잡한 포인터의 경우에는 반드시 annotation을 지정해주어야 합니다. 예를 들어, nullable 객체를 가리키는 non-nullable포인터는 _Nullable id * _Nonnull와 같이 선언해주어야 합니다.
    • NSError **타입은 메소드에서 에러를 리턴하는 파라미터로 주로 사용되는 타입입니다. 메소드가 항상 에러를 리턴하는 경우는 없을 것입니다. 따라서 NSError **타입은 항상 nullable NSError 타입을 갖습니다.
    에러에 관해서는 Error Handling Programming Guide를 참조해주세요.


    Compatibility

    "이미 nullable annotation을 적용하지 않은 프레임워크를 사용하고 있어요.  헤더에서 nullable annotation만 지정해주면 다른 코드에 지장이 없을까요?"

    대답은 "다른 코드에 지장이 없다."입니다.

    • nullable annotation을 적용하지 않은 프레임워크 파일 헤더에 nullable annotation을 추가해줘도 기존 앱은 정상적으로 작동합니다. (ABI는 바뀌지 않습니다.) 이는 런타임에서 원치 않게 nil이 전달 되는 경우도 없음을 의미합니다.
    • nullable annotation을 적용하지 않은 프레임워크를 사용하다가 annotation을 새롭게 적용시키면 컴파일 warning이 발생할 수는 있습니다.
    • nonnull이 최적화(optimization)에는 영향을 미치지 않습니다. 실제로 아직도 런타임에서 nonnull인 파라미터가 nil인지 아닌지를 확인하는 것이 가능합니다.
    nullable과 nonnull이 exception을 발생시킬 수 있으므로 주의해서 사용하셔야 합니다. 특히 리턴 타입에 신경을 좀 써주어야 하는데요, non-nullable 리턴타입에 nil을 리턴하지 않도록 주의해주어야 합니다.

    nullable과 nonnull키워드는 6.3버전에 릴리즈 되었지만 Third-party 라이브러리와의 충돌 가능성 때문에, 7.0버전에서 이와 같은 업데이트가 있었습니다.



    Back to Swift

    nullability annotation을 적용한 Objective-C 헤더를 스위프트가 바라볼 때,


    annotating을 하기 전에는 이랬던 코드가,


    annotating을 하고 난 뒤 이렇게 바뀌었습니다.

    미묘한 차이지만 바뀐 코드가 훨씬 좋아보이네요.

    Nullability annotations for C and Objective-C는 Xcode 6.3부터 지원됩니다.





    3줄요약

    1. nullability는 Swift의 Optional과 Objective-C코드의 호환을 위해서 사용함

    2. 포인터 타입에 nonnull또는 nullable을 지정해서 사용가능함.

    3. XCode 6.3부터 지원하고 있음


    출처 : https://developer.apple.com/swift/blog/?id=25


Designed by Tistory.