Foo类同时在MyApp和MyAppTestCase中实现。 将使用两者之一。 哪一个是未定义的
最近我开始unit testing我的应用程序。 这个项目(在Xcode4中)是在没有unit testing包的情况下创build的,所以我不得不进行设置。 我已经按照从这里的步骤: http : //cocoawithlove.com/2009/12/sample-mac-application-with-complete.html而且它对于简单的类很好,但现在我试图testing一个类,取决于在另一个和另一个等等
首先我得到了一个链接器错误,所以我添加了*.m
文件到testing用例目标,但现在我得到了每一个类,我试图testing的警告:
Foo类同时在MyApp和MyAppTestCase中实现。 将使用两者之一。 哪一个是未定义的
我不知道为什么呢? 我该如何解决这个问题? 也许我在设置unit testing目标时错过了一些东西?
编辑 – 解决scheme
-
将“Bundle Loader”正确设置为
$(BUILT_PRODUCTS_DIR)/AppName.app/AppName
-
将“默认隐藏的符号”设置为“ 否” (在目标应用程序的“生成设置”中)。 这是链接器错误来自哪里,因为它默认是YES! 我一直在努力这么久!
来源: unit testing与XCode 4链接错误?
Foo类同时在MyApp和MyAppTestCase中实现。 将使用两者之一。 哪一个是未定义的
我不知道为什么呢?
因为这两个图像(应用程序和unit testing包)定义了类的实现。 该类被dynamic加载到objc运行时。 objc运行时使用一个平面名称空间。 这是如何工作的:
- 二进制文件被加载,从它的依赖关系开始
- 当每个二进制文件被加载时,objc类将在objc运行时注册
- 如果具有特定名称的类被加载两次,则行为是未定义的。 可以将一个类的实现(名称相同)加载到objc运行时。
这里的典型问题是您将返回一个实现 – 当types冲突(当类不是来自同一个源文件时),您的应用程序可能会崩溃。
你通常通过重命名一个类或者在一个图像中导出类来避免这种情况。 重命名类明显不适用于你的情况。 你有一个文件Foo.m
正在编译,导出,并加载两个图像,当它应该在一个。
这应该被你解释为一个重复的符号链接器错误。 即使实现是相同的源文件(并且实现是相同的) – 这是您必须解决的问题。
我该如何解决这个问题?
如果Foo.m
是应用程序的一个类,则必须从unit testing中删除(不编译和链接) Foo.m
。 如果它是unit testing的一部分,则不要将其编译并链接到unit testing目标中。
然后,按照post中的说明链接/加载你的unit testing到应用程序。 这是在这个职位的一般领域: 其中“WhereIsMyMac”是您正在进行unit testing的应用程序的名称。 这将使testing目标与应用程序链接(所以编译时不会出现链接器错误)。 最重要的部分是你的testing文件被编译到unit testing目标(仅),你的应用程序的类被编译和链接到应用程序。 你不能只是添加他们 – 他们链接和dynamic加载。
也许我在设置unit testing目标时错过了一些东西?
从你链接的文章:
注意:testing目标是一个单独的目标。 这意味着你需要小心目标成员。 所有的应用程序源文件只能添加到应用程序目标中。 testing代码文件只能添加到testing目标。
错误的部分可能是unit testing包的链接和加载阶段。
如果你正在使用Cocoapods,你的podfile只需要主目标部分的依赖关系,而不是testing目标。 如果您为testing目标添加了重复的依赖关系,则会得到OP的错误消息。
target 'MyProject' do pod 'Parse' end target 'MyProjectTests' do end target 'MyProjectUITests' do end
对我而言,我所需要做的就是取消选中使Foo类成为unit testing目标成员的checkbox。 它不应该是两个目标的成员,应该是这样的:
如果你看不到图像,这是Xcode“目标成员”窗格的屏幕截图。 有两个目标:一个带有“A”应用程序图标和testing名称。 另一个是unit testing目标,并有一个unit testing图标:
Target Membership [X] Foo [ ] FooTests
对我来说,这是因为我部署到设备,然后到模拟器,因为我有NSZombies启用。 解决scheme是切换到模拟器configuration和做一个产品 – >清洁然后切换到设备configuration和做同样的。 错误消失了。 这是build立caching。
原因是你重写了其他目标中定义的App Target的构build设置的RUNPATH_SEARCH_PATHS。
解:
转到您的应用目标并find
RUNPATH_SEARCH_PATHS
构build设置,并在其中使用$(inherited)
标志: Debug和Release