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

mic*_*ken 37 xcode linker categories ios

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

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

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

平台是我通过类别添加的功能之一.

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

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

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

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

干杯

alb*_*amg 72

查看具有类别的构建Objective-C静态库:

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

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


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

来源:@albertamg(链接静态库中的objective-c类别)

  • 是的,该错误仍然存​​在于Xcode 4.3.3和iOS 5.1.1中. (3认同)
  • 看起来这不再是Xcode 4.5.2和iOS 6.0的问题.只需-ObjC标志即可. (3认同)
  • @micken重要:对于64位和iPhone OS应用程序,有一个链接器错误阻止-ObjC从仅包含类别而不包含类的静态库加载对象文件.解决方法是使用-all_load或-force_load标志. (2认同)

184*_*615 8

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

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

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

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