在静态库中链接objective-c类别

时间:2011-07-25 18:42:12

标签: ios xcode linker categories

我正在为iOS应用程序开发一个插件。我正在将它编译成一个.a文件,然后由主xcode项目使用。

到目前为止,我已在此库中创建了一个UIDevice类的类别。当我使用此库运行主项目时,由于无法识别的选择器

而崩溃

- [UIDevice platform]:无法识别的选择器发送到实例

平台是我通过类别添加的一种功能。

所以我认为它根本没有链接这些函数,并且将一个c函数添加到与UIDevice类相同的文件中,然后从我的代码中调用它。

这次主要项目运行正常...所以我想也许这是我做的其他事情并删除了C函数。但是,由于无法识别的选择器,它再次崩溃了。

我的问题: 为什么xcode忽略了类别定义,除非我调用在同一个文件中声明的函数?

是否有xcode设置我可以更改以使其包含来自UIDevice类别的这些方法,无论我是否从该文件调用函数?

欢呼声

3 个答案:

答案 0 :(得分:72)

结帐Building Objective-C static libraries with categories

  

Objective-C没有为每个函数定义链接器符号(或   在Objective-C)中的方法 - 而是仅生成链接符号   为每个班级。如果使用类别扩展预先存在的类,   链接器不知道关联核心的目标代码   类实现和类实现。这可以防止   生成的应用程序中创建的对象响应a   在类别中定义的选择器。

     

要解决此问题,请将目标链接到静态库   必须将-ObjC选项传递给链接器。此标志会导致链接器   加载定义Objective-C的库中的每个目标文件   班级或类别。虽然此选项通常会导致更大   可执行文件(由于附加的对象代码加载到   应用),它将使成功创造有效   Objective-C静态库,包含现有的类别   类。


  

重要:对于64位和iPhone OS应用程序,有一个   链接器错误,阻止-ObjC从静态加载对象文件   仅包含类别而不包含类的库。解决方法   是使用-all_load或-force_load标志。

来源:@albertamg(linking objective-c categories in a static library

答案 1 :(得分:8)

我遇到了同样的问题。在子项目中定义的类别中定义的方法导致无法识别的选择器异常。 (事实上​​,这表现为无法在Interface Builder中指定UILabel子类; XIB包含IB中显示的类(UILabel或UIView,取决于我拖动的那些),而不是我输入的类,并且看起来像一个奇怪的XCode bug。)

对我有用的解决方案是使用-force_load:

在左侧面板中,选择您的主项目(根项目)。在右侧,您会看到PROJECTTARGETS。选择TARGETS。 转到“构建设置”(在上方栏中) - “链接” - “其他链接器标志”,并假设您的子项目名为XXXXX,添加 -force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a 那里(该项有两个子项,Debug和Release,但是你点击这个复合项,这样如果同时影响Debug和Release)。

请注意,-force_load适用于单个库,您可能需要为每个子项目库指定单独的-force_load。

答案 2 :(得分:-1)

我有这个问题并花了将近1小时来解决它。感谢上帝!它已经完成了。定义的方法应该是静态类型!