iphone - 静态库中的 Objective-C 类别

你能指导我如何正确地将静态库链接到 iPhone 项目。我使用添加到应用程序项目中的静态库项目作为直接依赖项(目标 -> 常规 -> 直接依赖项)并且一切正常,但类别。静态库中定义的类别在应用程序中不起作用。

所以我的问题是如何将具有某些类别的静态库添加到其他项目中?

一般来说,在其他项目的应用项目代码中使用的最佳做法是什么?

最佳答案

解决方案:从 Xcode 4.2 开始,您只需转到链接库的应用程序(而不是库本身),然后单击项目导航器中的项目,然后单击应用程序的目标,然后build设置,然后搜索“Other Linker Flags”,单击 + 按钮,并添加“-ObjC”。不再需要“-all_load”和“-force_load”。

详情: 我在各种论坛、博客和苹果文档上找到了一些答案。现在我试着对我的搜索和实验做一个简短的总结。

问题是由(来自苹果技术问答 QA1490 https://developer.apple.com/library/content/qa/qa1490/_index.html 的引文)引起的:

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 static library should 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.

iPhone Development FAQ 中也有推荐:

How do I link all the Objective-C classes in a static library? Set the Other Linker Flags build setting to -ObjC.

和标志说明:

-all_load Loads all members of static archive libraries.

-ObjC Loads all members of static archive libraries that implement an Objective-C class or category.

-force_load (path_to_archive) Loads all members of the specified static archive library. Note: -all_load forces all members of all archives to be loaded. This option allows you to target a specific archive.

*我们可以使用 force_load 来减少应用程序二进制文件大小并避免 all_load 在某些情况下可能导致的冲突。

是的,它适用于添加到项目中的 *.a 文件。 然而,我在将 lib 项目添加为直接依赖项时遇到了麻烦。但后来我发现这是我的错 - 可能没有正确添加直接依赖项目。当我删除它并通过步骤再次添加时:

  1. 在app项目中拖放lib项目文件(或通过Project->Add to project...添加)。
  2. 单击 lib 项目图标上的箭头 - 显示 mylib.a 文件名,将这个 mylib.a 文件拖放到 Target -> Link Binary With Library 组中。
  3. 在第一页(常规)中打开目标信息并将我的库添加到依赖项列表中

之后一切正常。在我的情况下,“-ObjC”标志就足够了。

我也对 http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html 的想法很感兴趣博客。作者说他可以在不设置 -all_load 或 -Objcflags的情况下使用 lib 中的类别。他只是将空的虚拟类接口(interface)/实现添加到类别 h/m 文件中,以强制链接器使用此文件。是的,这个技巧可以完成这项工作。

但是作者也说他甚至没有实例化虚拟对象。嗯……正如我发现的那样,我们应该从类别文件中显式调用一些“真实”代码。所以至少应该调用类函数。 我们甚至不需要虚拟类。单个 c 函数也是如此。

所以如果我们把lib文件写成:

// mylib.h
void useMyLib();

@interface NSObject (Logger)
-(void)logSelf;
@end


// mylib.m
void useMyLib(){
    NSLog(@"do nothing, just for make mylib linked");
}


@implementation NSObject (Logger)
-(void)logSelf{
    NSLog(@"self is:%@", [self description]);
}
@end

如果我们调用 useMyLib(); App 项目中的任何地方 那么在任何类中我们都可以使用logSelf类方法;

[self logSelf];

还有更多关于主题的博客:

http://t-machine.org/index.php/2009/10/13/how-to-make-an-iphone-static-library-part-1/

http://blog.costan.us/2009/12/fat-iphone-static-libraries-device-and.html

https://stackoverflow.com/questions/2567498/

相关文章:

iphone - @synthesize 到底是做什么的?

objective-c - NSLog iPhone中Objective-C的方法名

iphone - 在 UIViewController 上显示 clearColor UIViewC

ios - 从 UITableView 单元格内的 url 异步加载图像 - 滚动时图像更改为错误图

objective-c - Xcode 构建失败 "Undefined symbols for ar

objective-c - Objective-C 中的 "unrecognized selecto

objective-c - 每个核心数据关系都必须有一个逆关系吗?

ios - 如何使用 AVAudioRecorder 在 iPhone 上录制音频?

objective-c - Xcode 5 : Code signing entitlement e

objective-c - 使用 Objective-C 在 iOS 9 中将状态栏文本颜色更改为浅