Foo类在MyApp和MyAppTestCase中实现。将使用两者之一。哪一个是未定义的 [英] Class Foo is implemented in both MyApp and MyAppTestCase. One of the two will be used. Which one is undefined

查看:160
本文介绍了Foo类在MyApp和MyAppTestCase中实现。将使用两者之一。哪一个是未定义的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我开始单元测试我的应用程序。这个项目(在Xcode4中)创建没有单元测试包,所以我不得不设置它。
我已按照以下步骤操作: http:/ /cocoawithlove.com/2009/12/sample-mac-application-with-complete.html
它对于简单的类工作良好,但现在我试图测试一个依赖另一个类的类,在另一个等等。



首先我得到一个链接器错误,所以我添加 *。m 文件到测试


类Foo在MyApp中实现
和MyAppTestCase。其中一个将
使用。


我不知道为什么会这样?我如何解决这个问题?在设置单元测试目标时,我可能错过了什么?



编辑 - 解决方案




  • 将Bundle Loader正确设置为 $(BUILT_PRODUCTS_DIR)/AppName.app/AppName


  • 将默认情况下隐藏的符号设置为(在目标应用程序的构建设置中)。这是链接器错误来自哪里,因为它默认为YES!




资料来源:使用XCode 4进行单元测试的链接错误?





,因为这两个图像(应用程序和单元测试包)定义类的实现。该类被动态加载到objc运行时。 objc运行时使用平面命名空间。如何工作:




  • 加载二进制文件,从它的依赖关系开始

  • objc类注册objc运行时

  • 如果具有特定名称的类被加载两次,行为是未定义的。可以将一个类(具有相同名称)的一个实现加载到objc运行时中。



这里的问题是你将返回一个实现 - 当类型冲突时(当类不是来自同一个源文件时),你的应用程序可能会崩溃。



通常通过重命名类或者在一个图像中导出类来避免这种情况。重命名类明显不适用于你的情况。您有一个文件 Foo.m 正在编译,导出和加载两个图像,当它应该在一个。



这应该被解释为一个重复的符号链接器错误。即使实现是相同的源文件(并且实现是相同的) - 这是一个必须修复的问题。


如何我解决了这个问题吗?


如果 Foo.m ,你必须从单元测试中删除(不编译和链接) Foo.m 。如果它是单元测试的一部分,那么不要编译并链接到单元测试目标。



然后,按照链接/加载您的单元的帖子中的说明测试到应用程序。它在这个一般的领域:其中WhereIsMyMac是您单元测试的应用程序的名称。这将让测试目标链接到应用程序(所以你不会在编译时得到链接器错误)。重要的是,你的测试文件是在单元测试目标(仅)和应用程序的类编译并链接到应用程序。


也许我在设置单元测试目标时错过了什么?


从您链接的文章:



注意:测试目标是单独的目标。这意味着你需要小心目标成员资格。所有应用程序源文件应仅添加到应用程序目标。测试代码文件应该只添加到测试目标。



您错误的部分是可能是单元测试包的链接和加载阶段。


Recently I started Unit testing my application. This project (in Xcode4) was created without a unit test bundle so I had to set it up. I have followed the steps from here: http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html And It was working well for simple classes but now I am trying to test a class that depends on another and that on another, etc.

First I got a linker error so I added *.m files to the test case target but now I get a warning for every class I am trying to test:

Class Foo is implemented in both MyApp and MyAppTestCase. One of the two will be used. Which one is undefined.

I wonder why is that? How can I solve this? Maybe I missed something when setting the unit test target?

Edit - The Solution

  • Set "Bundle Loader" correctly to $(BUILT_PRODUCTS_DIR)/AppName.app/AppName

  • Set "Symbols Hidden by Default" to NO (in Build Settings of the target application). This is where the linker errors come from because it is YES by default!. I've been struggling with this for so long!.

Source: Linking error for unit testing with XCode 4?

解决方案

Class Foo is implemented in both MyApp and MyAppTestCase. One of the two will be used. Which one is undefined.

I wonder why is that?

because both images (the app and the unit test bundle) define the implementation of the class. the class is dynamically loaded into the objc runtime. the objc runtime uses a flat namespace. how this works:

  • the binary is loaded, starting with its dependencies
  • as each binary is loaded, the objc classes register with the objc runtime
  • if a class with a specific name is loaded twice, the behaviour is undefined. one implementation of a class (with identical names) can be loaded into the objc runtime.

the typical problem here is that you will be returned one implementation - your app will likely crash when the type conflicts (when the class does not come from the same source file).

you typically avoid this by either renaming a class, or export the class in one image. renaming the class obviously does not apply to your case. you have one file Foo.m which is being compiled, exported, and loaded by two images when it should be in one.

this should be interpreted by you as a duplicate symbol linker error. even though the implementation is the same source file (and the implementation is the same) - this a problem that you must fix.

How can I solve this?

if Foo.m is a class of the app, you have to remove (do not compile and link) Foo.m from the unit test. if it's part of the unit test, then do not compile and link it into the unit test target.

then, follow the instructions in the post for linking/loading your unit test to the app. it's in this general area of the post: where "WhereIsMyMac" is the name of the application you're unit testing. This will let the testing target link against the application (so you don't get linker errors when compiling). the important part is that your test files are compiled in the unit test target (only), and your app's classes are compiled and linked into the app. you can't just add them - they link and load dynamically.

Maybe I missed something when setting the unit test target?

From the article you linked:

Note: The testing target is a separate target. This means that you need to be careful of target membership. All application source files should be added to the application target only. Test code files should be added to the testing target only.

the part that you got wrong is probably the link and load phases of the unit test bundle.

这篇关于Foo类在MyApp和MyAppTestCase中实现。将使用两者之一。哪一个是未定义的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆