使用iOS框架防止“重复符号”错误

使用iOS框架防止“重复符号”错误,ios,frameworks,duplicate-symbol,Ios,Frameworks,Duplicate Symbol,Apple在其所有框架类的标题中使用以下代码 #if !defined(__COREFOUNDATION_CFARRAY__) #define __COREFOUNDATION_CFARRAY__ 1 ... #endif 在设计用于框架的类或类别时,这是消除重复符号链接器错误的推荐方法,还是在c中使用include而不是import时留下的保护 对这一点的研究使我想到了这篇关于 注意:此问题不是询问如何修复重复符号错误,而是询问是否有任何方法可以防止您自己的代码在项目中多次包含时引发问题 A

Apple在其所有框架类的标题中使用以下代码

#if !defined(__COREFOUNDATION_CFARRAY__)
#define __COREFOUNDATION_CFARRAY__ 1
...
#endif
在设计用于框架的类或类别时,这是消除重复符号链接器错误的推荐方法,还是在c中使用include而不是import时留下的保护

对这一点的研究使我想到了这篇关于

注意:此问题不是询问如何修复重复符号错误,而是询问是否有任何方法可以防止您自己的代码在项目中多次包含时引发问题

Apple在其所有框架类的标题中使用以下代码

#if !defined(__COREFOUNDATION_CFARRAY__)
#define __COREFOUNDATION_CFARRAY__ 1
...
#endif
对于ObjC API不一定如此。但是CoreFoundation,是的,他们使用的包括警卫。在许多阵营中,在C源代码中使用传统的include仍然是惯用做法,而在objc源代码中使用import是一个编译器扩展,而不是传统的C

这是消除重复符号链接器错误的推荐方法吗

不,它不能防止链接器错误;在编译阶段,它可能会导致重复的声明错误

如果出现重复的符号链接器错误,则问题在于其他方面,例如定义的可见性。为此,您应该提供一个麻烦程序的示例

Apple在其所有框架类的标题中使用以下代码

#if !defined(__COREFOUNDATION_CFARRAY__)
#define __COREFOUNDATION_CFARRAY__ 1
...
#endif
对于ObjC API不一定如此。但是CoreFoundation,是的,他们使用的包括警卫。在许多阵营中,在C源代码中使用传统的include仍然是惯用做法,而在objc源代码中使用import是一个编译器扩展,而不是传统的C

这是消除重复符号链接器错误的推荐方法吗

不,它不能防止链接器错误;在编译阶段,它可能会导致重复的声明错误


如果出现重复的符号链接器错误,则问题在于其他方面,例如定义的可见性。为此,您应该提供一个麻烦程序的示例。

您对include-guard的看法是正确的-可能有一些兼容性原因导致它没有从源代码中删除

然而,这并不能真正保护您不受重复符号的影响

比如说,

如果您有两个第三方库,每个第三方库都使用SBJSON库,我几周前在一位同事身上遇到过这种情况

每个库都是单独编译的,因此从它们的角度来看,SBJSON只包含一次。然而,当我开始链接我的应用程序时,我无法链接,因为我有重复的符号

我必须通过手动删除其中一个.a库文件中的符号来解决此问题,这是一个非常常见的问题


编辑:是一个更清晰的逐步解决问题的方法

您对include-guard的看法是正确的-可能有一些兼容性原因导致它没有从源代码中删除

然而,这并不能真正保护您不受重复符号的影响

比如说,

如果您有两个第三方库,每个第三方库都使用SBJSON库,我几周前在一位同事身上遇到过这种情况

每个库都是单独编译的,因此从它们的角度来看,SBJSON只包含一次。然而,当我开始链接我的应用程序时,我无法链接,因为我有重复的符号

我必须通过手动删除其中一个.a库文件中的符号来解决此问题,这是一个非常常见的问题


编辑:这是一个更清晰的逐步解决问题的方法

我也在两个不同的框架中使用了SBJSON。没有什么可以做的,包括任何形式的运行时操作吗?你可以在编译之前修复它,在我的答案中的链接中向下滚动,有一些解决方案,但如果它无法编译,你无法在运行时修复:@Andrew-查看我的第二个链接,以获得更好的说明:你是对的,答案是否定的。我们只希望最初的库构建器没有直接包含其他库:删除所有的_加载会产生其他副作用,可能导致对象在运行时缺少方法,例如,如果对象上的类别包含未直接调用的方法,则链接器将不包含该类别除非所有_加载都作为标志传递。但是,其他一些代码可能会尝试动态调用这些方法并导致崩溃,因为它们丢失了:或者,您可以在类别实现之前使用宏定义一个空类:为了避免使用all_load或force_load,我在两个单独的框架中也使用了SBJSON。没有什么可以做的,包括任何形式的运行时操作吗?你可以在编译之前修复它,在我的答案中的链接中向下滚动,有一些解决方案,但如果它无法编译,你无法在运行时修复:@Andrew-查看我的第二个链接,以获得更好的说明:你是对的,答案是否定的
. 我们只希望原始库构建器没有直接包含其他库:删除所有的\u加载会产生其他副作用,可能会导致对象在运行时缺少方法,例如,如果对象上的某个类别包含未直接调用的方法,则链接器不会包含该类别,除非所有的\u加载都被删除作为旗帜通过。然而其他一些代码可能会尝试动态调用这些方法并导致崩溃,因为它们丢失了:或者,您可以在类别实现之前使用宏定义一个空类:避免使用all_load或force_load,这样非公共框架头将不会导致重复的符号错误?@Andrew it当然可以。因此公共框架标头不会导致重复的符号错误?@Andrew它当然会。