- 애플도 옵씨가 많다. 이걸 어떻게 잘 고칠 것인가?
- Xcode에서 헤더만 보고 swift로 인터페이스를 바로 만들 수 있다.
- Objective-C를 어떻게 써야 되는가
- Objective-C는 모든게 포인터기 때문에 바꾸면 암시적 옵셔널로 바뀐다.
- nonnull, nullable을 활용하면 된다.
- 이게 한번 쓰이기 시작하면 엑스코드가 모든 곳에서 사용할 것을 요구한다.
- NS_ASSUME_NOTNULL_BEGIN, NS_ASSUME_NOTNULL_END 로 감싸면 해당 영역 안의 변수는 모두 notnull이 기본 값으로 취급된다.
- Method나 Property는 notnull, nullable, 다른 포인터들은 _Nonnull, _Nullable로 수식
- 만약 notnull했는데 null이면?
- 시스템 타입이면 적절한 기본값으로 바뀔 것이다.
- 커스텀 타입이면 UB
- 그래도 엑스코드가 그런 부분을 잡아낼 것이다.
- 암시적 옵셔널이 그래도 필요하다면?
- null_unspecified, _Null_unspecified 사용
- NSArray가 [Any]로 바뀌는 것은? -> Objective-C에 제네릭 적용
- NSUInteger가 UInt로 바뀌는 것은?
- swift에서 UInt은 비트 연산을 할때 쓴다.
- 음수가 안되더라도, NSInteger로 쓰자
- 특정 문자열만 받도록 설계된 API라면?
- typedef로 특정 타입만 쓰는 것처럼 보이게 만들자
- NS_STRING_ENUM으로 Enum으로 만들 수도 있다.
- 생성자 문제
- NS_DESIGNATED_INITIALIZER 제공
- 다만 옵씨에서는 강제가 아니고 일부 클래스만 따르는 규칙이다.
- 사용하면 안되는 생성자는 NS_UNAVAILABLE
- 에러 처리 컨벤션을 준수하라
- 스로우가 안되는 메소드면 NS_SWIFT_NOTHROW 표시(스위프트와 옵씨는 에러 처리 방식이 다르다)
- error가 nil이여도 에러가 날 수가 있다.
- 아예 다른 방식을 제공할꺼면 DEPRECATED_ATTRIBUTE를 해라
- 옵씨 컨벤션을 잘 지키면, throw로 고쳐줄 것이다.
- 스위프트 헤더를 옵젝씨 헤더에서 임포트 하지말라. 구현체에서만 하라.
- Swift의 Bool과 ObjcBool은 다르다. 보통은 자동으로 컨버전 해주지만, 포인터로 하면 다른다.
- 이때는 명시적으로 바꿔줘야 한다.
- 이걸 하기 그렇다면, 옵젝씨 쪽에 _NS_REFINED_FOR_SWIFT를 써주면 된다.
- 이때 메소드는 언더바 2개를 붙여서 호출하면 된다.
- swift가 import할 수 없는 것들
- C-Style의 가변 인자
- C의 크기가 정해지지 않은 배열
- 완전히 정의되지 않은 클래스나 프로토콜(Forward declaration)
- 유효하지 않은 재정의
- import할 수 없는 타입을 사용한 선언
- 복잡한 매크로
- 편의성 높이기
- NS_SWIFT_NAME 매크로로 원하는 메소드 명을 지정해 줄 수 있다.
- 메소드 뿐 아니라 Enum도 되고, Extension 식으로도 된다.
NS_SWIFT_NAME(SKFuel.Kind)