xcode 链接静态库中的objective-c 类别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6820778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 21:33:48  来源:igfitidea点击:

linking objective-c categories in a static library

iosxcodelinkercategories

提问by micken

I am developing a plugin for an iOS application. I am compiling it into a .a file which is then used by the main xcode project.

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

So far I have create a category of the UIDevice class in this library. When I run the main project using this library it crashes due to an unrecognized selector

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

-[UIDevice platform]: unrecognized selector sent to instance

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

platform is one of the fuinctions I added via the category.

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

So I thought it wasn't linking those functions at all and added a c function to the same file as the UIDevice category then called it from my code .

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

This time the main project ran fine... So I thought maybe it was something else i did and removed the C function. But lo and behold it crashed again due to unrecognized selector..

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

My questions: Why does xcode ignore the category definition unless I call a function declared in the same file?

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

Is there an xcode setting i can change to make it include these methods from the UIDevice category regardless of whether I call a function from that file or not?

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

cheers

干杯

回答by albertamg

Check out Building Objective-C static libraries with categories:

查看使用类别构建 Objective-C 静态库

Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.

To resolve this issue, the target linking against the static library must pass the -ObjC option to the linker.This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

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

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



Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -all_load or -force_load flags.

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

Source: @albertamg (linking objective-c categories in a static library)

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

回答by 18446744073709551615

I have had the same problem. A method defined in a category defined in a subproject resulted in an unrecognized selector exception. (In fact, this manifested as inability to specify an UILabel subclass in Interface Builder; the XIB contained the class shown in IB (UILabel or UIView, depending on what I dragged there), rather than the class that I have typed in, and that looked as a weird XCode bug.)

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

The solution that worked for me has been to use -force_load:

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

In the left-hand panel, select your main project (the root item). On the right, you will see PROJECTand TARGETS. Select TARGETS. Go to "Build Settings"(in the upper bar) -- "Linking" -- "Other linker flags" and, assuming your subproject is called XXXXX, add -force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.athere (the item has two subitems, Debug and Release, but you click on this compound item so that if affects both Debug and Release).

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

Note that -force_load works for a single library, and you may need to specify a separate -force_load for each subproject library.

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

回答by Binh Le

I had this issue and spent near 1 hour to resolve it. Thanks god! it's been done. Methods which are defined should be static type!

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