在静态库中链接 Objective-C 类别

发布于 2024-11-26 02:03:29 字数 459 浏览 0 评论 0原文

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

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

-[UIDevice platform]:发送到实例

平台的无法识别的选择器是我通过类别添加的功能之一。

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

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

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

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

干杯

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.

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 platform]: unrecognized selector sent to instance

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 .

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..

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

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?

cheers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水中月 2024-12-03 02:03:29

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

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

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


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

资料来源:@albertamg(链接静态库中的 Objective-C 类别)

Check out Building Objective-C static libraries with categories:

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.


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.

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

爱的故事 2024-12-03 02:03:29

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

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

在左侧面板中,选择您的主项目(根项目)。在右侧,您将看到 PROJECTTARGETS。选择目标
转到“Build Settings”(在上方栏中)--“Linking”--“Other linker flags”,假设您的子项目名为 XXXXX,添加
-force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a
(该项目有两个子项目,“调试”和“发布”,但您单击此复合项目,以便同时影响“调试”和“发布”)。

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

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.)

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

In the left-hand panel, select your main project (the root item). On the right, you will see PROJECT and 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.a
there (the item has two subitems, Debug and Release, but you click on this compound item so that if affects both Debug and Release).

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

一曲琵琶半遮面シ 2024-12-03 02:03:29

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

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文