代码之家  ›  专栏  ›  技术社区  ›  makdad

Xcode如何处理多个目标中的import header语句?

  •  2
  • makdad  · 技术社区  · 15 年前

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

    我的解决方案(不工作)是将2个子目录添加到我的 Classes/ 我的项目目录中的文件夹-每个目标一个。在每个目录中,我都放置了一个视图控制器类,名为 ExampleSentencesViewController . 当然,每个文件都是作为目标之一的一部分编译的——我正在寻找一个“自动切换”,其中的实现将基于目标使用。

    在每个目标的设置中,我将每个目录添加到“头搜索路径”设置(每个目标的每个路径)。

    奇怪的是,它只为原始目标编译。我后来添加的目标不会编译,声称我已经包含了同一个头部两次(公平地说,有两个文件)。如何让Xcode忘记原始头段??

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

    感谢您的帮助。

    1 回复  |  直到 15 年前
        1
  •  3
  •   justin    15 年前

    根据您定义的搜索目录完全限定单独实现文件中的头路径:

    #include <MONProject/Source/ExampleSentencesViewController.h>

    VS

    #include <MONSecondProject/Source/ExampleSentencesViewController.h>

    基于澄清的更新:

    理想情况下,您应该为共享代码创建一个静态库。

    对于一个简单的例子…你 能够 通过在项目根目录中填充头来直接方法 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
    

    _,但这需要在您的分发中包含两个标题(如果适用)。

    根据您声明搜索路径的方式(例如,它们是否递归),包含的一些更精细的细节可能会有所不同。以及是否在xcodeproj中使用复制头构建阶段。如果您对include指令、发现选项、预处理器声明(条件编译/可见性)和/或构建配置过于宽松,那么维护共享代码的两个项目可能会变得混乱,因此…这就是为什么我推荐一个共享位的库。这种有条件的东西(在前面的两个例子中)是容易出错的,不能很好地发展或扩展。这样做也是混淆开发工具包中其他工具的一个好方法。

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

    - (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;
        }
    }
    

    如果您只是维护同一标题的两个版本,那么实践将大不相同。

    不管怎样…这 应该 有足够的想法来解决你的问题-你只需要确定较小的邪恶。