博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Xcode 5.1 编译模拟器以及真机都能使用的静态库
阅读量:4911 次
发布时间:2019-06-11

本文共 4693 字,大约阅读时间需要 15 分钟。

Xcode 5.1.dmg 下载地址

 

1.新建 Framework & Library 工程

我起名叫ShowInfo,下面为其源码

showInfo.h

=========================

#import <Foundation/Foundation.h>

@interface ShowInfo : NSObject
+ (void)showInfo;
@end

=========================

showInfo.m

=========================

#import "ShowInfo.h"

@implementation ShowInfo
+ (void)showInfo
{
    NSLog(@"hello Y.X.");
}
@end

=========================

 

2.分别制作真机以及模拟器使用的静态库

如上图所示,Debug-iphoneos以及Debug-iphonesimulator都有一个静态库文件

 

3.合并静态库

合并静态库的格式如下所示

lipo -create /绝对路径/libShowInfo.a  /绝对路径/libShowInfo.a  -output /绝对路径/libShowInfo.a

大功告成!

 

以下为 Xcode 5.1 测试结果

无意间发现 Xcode 5.1 中的静态库 Search Paths 中的路径为 $(PROJECT_DIR) ,以后再也不会出现换台电脑后重新设置库搜索路径的问题了.

以下为 Xcode 5.0 测试结果

 

 

问:如果有很多文件,如何编译成一个静态库文件?

如上例中,我将一个操作CoreData的很多文件打包成一个静态库,编译时把需要导出的头文件导出来即可(图片右下部分).

 

问:为什么在使用静态库时报错呢?

极有可能你的静态库文件中含有类目文件,就以上图中为例,有很多的类目文件,解决方法在 Other Linker Flags 是添加 -ObjC 标签,如下图所示

原理解析如下

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.

Problem was caused by (citation from apple Technical Q&A QA1490 ):

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.

And their solution:

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.

and there is also recommendation in 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.

and flags descriptions:

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

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

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 projecct possibly was not added properly. When I remove it and add again with steps:

  1. Drag&drop lib project file in app project (or add it with Project->Add to project…).
  2. Click on arrow at lib project icon - mylib.a file name shown, drag this mylib.a file and drop it into Target -> Link Binary With Library group.
  3. Open target info in fist page (General) and add my lib to dependencies list

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

I also was interested with idea from 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.

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.

So if we write lib files as:

// mylib.hvoid useMyLib();@interfaceNSObject(Logger)-(void)logSelf;@end// mylib.mvoid useMyLib(){
NSLog(@"do nothing, just for make mylib linked");}@implementationNSObject(Logger)-(void)logSelf{
NSLog(@"self is:%@",[self description]);}@end

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

[self logSelf];

And more blogs on theme:

 

问:合并静态库时为什么会报错?

请将你正在使用的 Xcode 的 APP 文件名字修改成Xcode.app,否则在终端合并库文件时会报错.

转载于:https://www.cnblogs.com/YouXianMing/p/3595945.html

你可能感兴趣的文章
mysql安装及常见问题
查看>>
Thinkphp .htaccess 与 httpd.ini文件重定向转换问题
查看>>
gulp-less解决遇到错误停止执行task
查看>>
一些很少用又很常见的功能的实现方法链接
查看>>
20145235《信息安全系统设计基础》第十二周学习总结
查看>>
响应式布局 大中小屏幕
查看>>
iOS开发UI篇—transframe属性(形变)
查看>>
java中的单例模式
查看>>
Elasticsearch Server,2nd Edition pdf 翻译 中文
查看>>
Django-缓存
查看>>
[无关IT]就这样在凌晨写一篇吧~
查看>>
java.util.Map.Entry接口
查看>>
Linux中crond服务与crontab用法
查看>>
PLSQL连接ORACLE配置字符串简介 oracle网络配置 三个配置文件 listener.ora、sqlnet.ora、tnsnames.ora原理解释...
查看>>
分享8年开发经验,浅谈个人发展经历,明确自己发展方向
查看>>
开发使用Node.js的一个小技巧
查看>>
Mike的农场 BZOJ4177
查看>>
IT职场人生系列
查看>>
如何指定个别属性进行transition过渡
查看>>
Python爬虫基础--分布式爬取贝壳网房屋信息(Client)
查看>>