XCode如何处理多个目标中的#import标题语句?

我有一个2个目标的XCode项目(两个iPhone应用程序共享95%的相同的代码)。 但是,一个模块不是“可共享的”; 实现太不同了。

我的解决scheme(不工作)是添加2个子目录到我的项目目录中的Classes/文件夹 – 每个目标一个。 在每个目录中,我放置了一个名为ExampleSentencesViewController的视图控制器类。 当然,每个文件都被编译为只有一个目标的一部分 – 我正在寻找一个“自动切换”,根据目标使用哪个实现。

在每个目标设置中,我将每个目录添加到“标题searchpath”设置(每个目标的每个path)。

奇怪的是,它只能编译原来的目标。 我稍后添加的目标将不会编译,声称我已经包含相同的头两次(有两个文件,公平)。 我如何让XCode忘记原始标题?

我已经尝试从我的项目中删除.h文件,但似乎没有帮助。

任何帮助表示赞赏。

根据您定义的search目录之一,在单独的实现文件中完全限定标题path:

#include <MONProject/Source/ExampleSentencesViewController.h>

VS

#include <MONSecondProject/Source/ExampleSentencesViewController.h>

根据澄清更新:

理想情况下,您需要为共享代码创build一个静态库。

对于一个简单的例子…你可以采取直接的方法,在你的项目的根目录中填充一个名为ExampleSentencesViewController.h的头文件,并像下面这样填充它:

 /* you must define either MON_BUILD_MON_FIRST_PROJECT or MON_BUILD_MON_SECOND_PROJECT at the target level */ #if (defined(MON_BUILD_MON_FIRST_PROJECT) && defined(MON_BUILD_MON_SECOND_PROJECT)) #error invalid configuration: you cannot specify both projects to be compiled #elif defined(MON_BUILD_MON_FIRST_PROJECT) /* some fully qualified path: */ #include <MONFirstProject/ExampleSentencesViewController.h> #elif defined(MON_BUILD_MON_SECOND_PROJECT) /* some other fully qualified path: */ #include <MONSecondProject/ExampleSentencesViewController.h> #else #error uh... which project are you trying to build? #endif 

也可以使用这些定义来有条件地启用/禁用具有重复名称的类的接口和实现(然后将它们都包含在项目的声明中:

 /* MONFirstProject/ExampleSentencesViewController.h> */ #if defined(MON_BUILD_MON_FIRST_PROJECT) @interface ExampleSentencesViewController : NSViewController /* ... */ @end #endif 

…但是这将需要在您的发行版中包含两个标头(如果适用)。

包含的一些更精细的细节可以根据你如何声明你的searchpath(例如,它们是recursion还是不是?)以及是否在xcodeproj中使用复制头构build阶段而有所不同。 如果您在include指令,发现选项,预处理器声明(条件编译/可见性)和/或构buildconfiguration方面过于宽松,那么维护这两个共享代码的项目可能会变得混乱,这就是为什么我推荐共享库位。 这个有条件的东西(在前面的两个例子中)是容易出错的,并且不能很好地进化或者扩展。 这样做也是混淆开发工具包中的其他工具的好方法。

事实上,我更喜欢这个预处理器(假设你能够分发这两个类):

 - (UIViewController *)newViewControllerForMyAwesomeView { if (IsAppMONFirstProject) { return [[MONFirstProjectViewController alloc] init...]; } else if (IsAppMONSecondProject) { return [[MONSecondProjectViewController alloc] init...]; } else { assert(0 && "definitely break up your code, now that it is referenced by 3 or more projects"); return 0; } } 

如果你只是维护同一个头衔的两个版本,那么实践将会有很大的不同。

反正…这应该是足够的想法来解决你的问题 – 你只需要确定较小的邪恶。