静态库中的Objective-C类别 [英] Objective-C categories in static library

查看:139
本文介绍了静态库中的Objective-C类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您能指导我如何正确地将静态库链接到iPhone项目。我使用添加到app项目的静态库项目作为直接依赖(目标 - >一般 - >直接依赖)并且所有工作正常,但是类别。静态库中定义的类别在app中不起作用。

Can you guide me how to properly link static library to iPhone project. I use static library project added to app project as direct dependency (target -> general -> direct dependencies) and all works OK, but categories. A category defined in static library is not working in app.

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

So my question is how to add static library with some categories into other project?

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

And in general, what is best practice to use in app project code from other projects?

推荐答案

解决方案:从Xcode 4.2开始,您只需要转到链接库(而不是库本身)的应用程序,然后单击Project Navigator中的项目,单击应用程序的目标,然后构建设置,然后搜索其他链接器标志,单击+按钮,然后添加-ObjC。不再需要'-all_load'和'-force_load'。

Solution: As of Xcode 4.2, you only need to go to the application that is linking against the library (not the library itself) and click the project in the Project Navigator, click your app's target, then build settings, then search for "Other Linker Flags", click the + button, and add '-ObjC'. '-all_load' and '-force_load' are no longer needed.

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

Details: I found some answers on various forums, blogs and apple docs. Now I try make short summary of my searches and experiments.

问题是由(引自苹果技术Q& A QA1490 https://developer.apple.com/library/content/qa/qa1490/_index.html ) :

Problem was caused by (citation from apple Technical Q&A QA1490 https://developer.apple.com/library/content/qa/qa1490/_index.html):


Objective-C没有为每个函数(或方法,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.

他们的解决方案:


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

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开发常见问题中的建议:

and there is also recommendation in iPhone Development FAQ:


如何链接静态库中的所有Objective-C
类?将
Other Linker Flags构建设置设置为
-ObjC。

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

和标记说明:


- all_load 加载静态归档库的所有成员。

-all_load Loads all members of static archive libraries.

- ObjC 加载实现
Objective-C类或类别的静态归档库的所有成员。

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

- force_load (path_to_archive)加载指定的静态
归档库的所有成员。注意:-all_load
强制加载所有档案的所有成员
。此选项允许您
定位特定存档。

-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可能导致的冲突。

*we can use force_load to reduce app binary size and to avoid conflicts which all_load can cause in some cases.

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

Yes, it works with *.a files added to the project. Yet I had troubles with lib project added as direct dependency. But later I found that it was my fault - direct dependency project possibly was not added properly. When I remove it and add again with steps:


  1. 在应用程序项目中拖放lib项目文件(或使用Project-> Add添加它项目...)。

  2. 单击lib项目图标上的箭头 - 显示mylib.a文件名,拖动此mylib.a文件并将其放入Target - > Link Binary With Library组。

  3. 在第一页打开目标信息(常规)并将我的lib添加到依赖列表

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

after that all works OK. "-ObjC" flag was enough in my case.

我也对 http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html 博客。作者说他可以使用lib中的类别而不设置-all_load或-ObjC标志。他只是添加类别h / m文件空虚拟类接口/实现来强制链接器使用这个文件。是的,这个技巧完成了这项工作。

I also was interested with idea from http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html blog. Author say he can use category from lib without setting -all_load or -ObjC flag. He just add to category h/m files empty dummy class interface/implementation to force linker use this file. And yes, this trick do the job.

但作者还说他甚至没有实例化虚拟对象。嗯......正如我发现我们应该从类别文件中明确地调用一些真实代码。所以至少应该调用类函数。
我们甚至不需要虚拟课程。单c功能也是如此。

But author also said he even not instantiated dummy object. Mm… As I've found we should explicitly call some "real" code from category file. So at least class function should be called. And we even need not dummy class. Single c function do the same.

因此,如果我们将lib文件写为:

So if we write lib files as:

// 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类别方法;

and if we call useMyLib(); anywhere in App project then in any class we can use logSelf category method;

[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

这篇关于静态库中的Objective-C类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆