어느날 @objc Inference 와 관련된 경고를 보았다
Xcode 9 이전에 개발했던 프로젝트를 Xcode 9 에서 Swift 4 기반으로 변경한 적이 있다. 이 과정에서 단 한줄의 코드 변경도 없었고, 당연하게도 해당 프로젝트는 별 문제는 없이 잘 동작하였다.
다만 약간 찝찝하게도 빌드 도중 아래와 같은 색다른(?) 경고를 보게 되었다.
Xcode 9 에서 지원하는 Swift 4 Migration 기능을 사용해 보는 도중 아래와 같은 다이얼로그를 보게 되었다.
위의 경고 문구와 아주 흡사만 문구들이 보인다. 도데체 무슨 표현일까. 물론 둘 중 위의 것은 Swift 4 에 해당하는 것이라고 유추가 가능하다. Swift 4 로 이주하고 싶다면 위의 것을 고르는 것이 맞을 것 같다는 이야기다.
물론 경고가 큰 문제는 아니고 여기서 선택하는 것도 뭐든 큰 문제를 일으키는 건 아니다. 선택은 개인의 자유다.
위 스크린샷의 선택된 항목인데, Swift 4 를 사용 중일때 이 값이 On 으로 설정되어 있으면 문제의 경고가 발생한다.
문제의 경고를 없애고 싶다면 이 값을 위 스크린샷 처럼 'Default' 로 교체하면 된다. 물론 완벽하게 해결하고 싶다면 아래 해설을 마저 읽어보자.
결국 빌드설정 변경 만으로는 완전무결(?)한 해결은 안되고, Objective-C 호환성을 위한 코드를 점검해야 할 필요성이 있다. 물론 몽땅 @objc 를 붙이거나 클래스를 @objcMembers 로 선언해 버리면 되기도 하지만 성격에 따라 할 일의 양이 달라질 것 같다. :-D
이제 앞서 본 Swift 4 마이그레이션 다이얼로그의 Minimize Inference 라는 말의 의미를 대충 알 수 있지 않을까.
[관련글] Swift 4 에서 KVO 사용해보기
[관련글] 스위프트(Swift) 가이드
다만 약간 찝찝하게도 빌드 도중 아래와 같은 색다른(?) 경고를 보게 되었다.
The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the "Swift 3 @objc Inference" build setting to "Default" for the "TARGET NAME" target.해석하자면 뭐라고 할까... 그냥 구버전 방식의 @objc 를 사용하는 것이 Swift 4 에선 호환이 안되니 무슨무슨 설정을 바꿔라 이런 의미로 해석된다. 하여간, 이 글은 이 경고를 해결하는 방법을 설명한다.
원인은 무엇일까?
명확한 이유는 모른채 원인을 추적하는 어이없는 짓을 좀 했는데, 그래도 뭔가 원인스러운 것을 찾게 되었다.Xcode 9 에서 지원하는 Swift 4 Migration 기능을 사용해 보는 도중 아래와 같은 다이얼로그를 보게 되었다.
위의 경고 문구와 아주 흡사만 문구들이 보인다. 도데체 무슨 표현일까. 물론 둘 중 위의 것은 Swift 4 에 해당하는 것이라고 유추가 가능하다. Swift 4 로 이주하고 싶다면 위의 것을 고르는 것이 맞을 것 같다는 이야기다.
물론 경고가 큰 문제는 아니고 여기서 선택하는 것도 뭐든 큰 문제를 일으키는 건 아니다. 선택은 개인의 자유다.
문제의 해결
사실 경고문구에서도 해결법이 잘 적혀있다. 타겟(Target) 빌드 설정(Build Settings)에서 Swift 3 @objc Inference 항목을 찾아보면 된다.위 스크린샷의 선택된 항목인데, Swift 4 를 사용 중일때 이 값이 On 으로 설정되어 있으면 문제의 경고가 발생한다.
문제의 경고를 없애고 싶다면 이 값을 위 스크린샷 처럼 'Default' 로 교체하면 된다. 물론 완벽하게 해결하고 싶다면 아래 해설을 마저 읽어보자.
해설 및 마무리
경고 수준의 문제라 그냥 넘어 갈수도 있는 것으로 봐도 되겠지만, 명확한 이유나 근거를 알지 못하면 좀 답답할 수도 있다. 그래서 정리해 보자면 이렇다.- @objc 는 Swift 코드를 Objective-C 에서 인식할 수 있게 해 주는 특수한 키워드다.
- Swift 4 이전에는 특수한 경우, 예를 들어 NSObject 를 상속받은 Swift 의 클래스는 자동으로 모든 멤버에 @objc 가 붙는 식으로 컴파일 되었다. 이렇게 자동으로 @objc 가 붙는 형태로 빌드하는 걸 @objc Inference 라고 부른다.
- @objc Inference 는 순수한 Swift 클래스에 Objective-C 의 온갖 기능을 집어넣게 된다. 즉 무거워진다.
- Swift 4 부터는 이런 경우의 경량화를 위해 @objc Inference 를 만료(deprecated)시켰다. 즉 이제는 NSObject 상속 여부와 관계 없이 필요한 곳에 @objc 를 붙여 쓰라는 말이다.
- 빌드 설정을 통해 @objc Inference 를 켤 수도 있다.
- Swift 4 에서는 클래스 멤버에 몽땅 @objc 를 자동으로 붙이기 위해 @objcMembers 키워드가 생겼다는 것을 기억하자.
결국 빌드설정 변경 만으로는 완전무결(?)한 해결은 안되고, Objective-C 호환성을 위한 코드를 점검해야 할 필요성이 있다. 물론 몽땅 @objc 를 붙이거나 클래스를 @objcMembers 로 선언해 버리면 되기도 하지만 성격에 따라 할 일의 양이 달라질 것 같다. :-D
이제 앞서 본 Swift 4 마이그레이션 다이얼로그의 Minimize Inference 라는 말의 의미를 대충 알 수 있지 않을까.
[관련글] Swift 4 에서 KVO 사용해보기
[관련글] 스위프트(Swift) 가이드
댓글
큰 도움이 되었습니다. 감사합니다.