티스토리 뷰

728x90
반응형

저는 얼마전에 Unit Test를 돌리면 

 

objc[60376]: Class _TtC4RIBs6Worker is implemented in both ~/Library/Developer/CoreSimulator/Devices/3A6725C3-27B5-4AD4-AE45-74695DC574BD/data/Containers/Bundle/Application/EEED6AE8-0469-42AD-84F2-B470FFB6CFCE/SimpleMemo.app/Frameworks/RIBs.framework/RIBs (0x104851920) and ~/Library/Developer/Xcode/DerivedData/SimpleMemo-gpgaamoyiqvqbnaehzbepweorlts/Build/Products/Debug-iphonesimulator/SimpleMemo.app/PlugIns/SimpleMemoTests.xctest/SimpleMemoTests (0x105692838). One of the two will be used. Which one is undefined.

 

이런 에러가 여러 클래스에서 엄청많이 나면서 크래쉬가 났었습니다...!!! 😱 

 

😇 천사같은 분 😇이 도와주셔서 원인을 찾았는데요,

 

이전 제 Podfile은 이렇게 앱 타켓아래 use_frameworks!가 있었습니다. 

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SimpleMemo' do
    use_frameworks!
    pod 'RxCocoa', '~> 4.0'
    pod 'Firebase/Core'
    pod 'Firebase/Database'
    pod 'Firebase/Auth'
    pod 'RIBs', '~> 0.9'
end


target 'SimpleMemoTests' do
    pod 'RIBs', '~> 0.9'
end

 

하지만 use_frameworks! 을 앱 타켓과 테스트 타켓 위에 위치하니 신기하게도 크래쉬가 안나고 테스트가 잘 돌았습니다.. 

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
use_frameworks!

target 'SimpleMemo' do
    pod 'RxCocoa', '~> 4.0'
    pod 'Firebase/Core'
    pod 'Firebase/Database'
    pod 'Firebase/Auth'
    pod 'RIBs', '~> 0.9'
end


target 'SimpleMemoTests' do
    pod 'RIBs', '~> 0.9'
end

 

저는 use_framework!가 앱 타켓 아래있는 지도 눈치못채고 쓰고 있었는데요 (처음 pod init으로 podfile을 만들면 저기 들어가있더라구요.)

https://github.com/uber/RIBs/blob/master/ios/tutorials/tutorial2/Podfile RIBs 튜토리얼 예제의 Podfile을

매의 눈으로 살펴보다가 알게 되었습니다. 

 

use_frameworks! 를 쓰면 dynamic framework 임을 나타냅니다.

use_frameworks!를 안쓰면 static library 임을 나타냅니다.

 

static library (정적 라이브러리)는 컴파일 시에 라이브러리 코드가 실행파일에 연결됩니다. 

즉 라이브러리 코드가 실행 파일에 복사되어, 실행파일에 라이브러리 코드가 포함되어있는 상태로 컴파일 되는 것입니다. 

 

반면 dynamic framework (동적 라이브러리) 는 런타임 시에 라이브러리 코드가 실행파일에 연결됩니다.

실행파일에는 호출할 라이브러리의 정보만 포함되고 실제 라이브러리 코드는 복사되지 않습니다. 

 

그래서 테스트 타겟에서는 " RIBs와 RIBs가 물고있는 Rxswift 라이브러리"가 컴파일시에 복사되어 실행파일에 들어가 있고 

앱 타겟에서는 " RIBs와 RIBs가 물고있는 Rxswift 라이브러리"가 동적으로 실행파일에 연결되려고 하고???!!!

 

두 개가 충돌해서 두 개가 다 있는데 어떤 것을 쓸지 모르겠다!!! 하고 크래쉬가 나는 상황인 것 같다고 예측됩니다.

 

(하지만 신기하게도 use_framework!를 앱 타켓 아래에 위치시키고 테스트 타켓에 RIBs를 빼고 kingfisher를 넣어보면 크래쉬안나고 테스트가 잘돌아갑니다...(??) 두개의 차이는 무엇일까요.. ) 

 

 

 

 

아무튼 크래쉬 날때 Call Stack이 RIBs의 코드에서 출발해서 RIBs쪽 문제인줄 알았는데 저의 Podfile 문제였습니다....충격(😱) 

 

혹시 저처럼 테스트가 안돌아가서 고생하게 되신다면!!!

Podfile의 use_framework! 위치를 살펴보세요!!!@@ 

 

 

반응형
댓글