(iOS)谈谈关于使用category的静态库(原创)
最近在一个项目中使用了一个包含catecategory 的静态库,但是此项目在运行过程中,该静态库调用 category 增加的方法处,却报 selector not recognized 异常,会直接crash。
我的开发环境是xcode5.0。
在网上查了一下原因和解决的办法,在此做个总结。
产生这个问题的原因,苹果官方提供的文档,Q&A QA1490:Building Objective-C static libraries with categories
在连接一个含有category的静态库的时候,往往会得到一个运行时exception “selector not recognized”。这是由于 UNIX的静态库实现、linker和Objective-C的动态结构三者之间的问题引起的。
Objective-C并不为每个函数定义linker symbol,它只为每个class生成linker symbol。(objc的动态结构)如果你为一个已存在的class创建了category,那么linker并不知道要将原始class实现和category实现联系起来。这就导致了最终程序中的对象没法响应category中的方法。
为了解决这个问题,目前我知道以下几个方法:
1.将category文件跟静态库一起导入到工程。
这让很多想保持工程独立性,并且有代码洁癖的人感觉很不舒服,包括我,随着这个是非常直接并且简单的方法,但是不能保持静态库的独立性,而且多个地方存在同一份文件,可能会带来另外一些问题。
2.在使用静态库的 target 要将 -ObjC 选项传递给 linker,这个标志将会使得 linker 将静态库中原始类及 category 的类文件都载入!
设置 -ObjC 选项对于 iOS 程序来说有时是不够的,这是因为 linker 中存在一个 bug,所以还是可能会在 -ObjC 的情况下导致 selector not recognized 的异常,为了避免这个 bug,在 Other Linker Flags 中,我们将其值设置为 -all_load 或者 -force_load 即可。
-all_load 与 -force_load 说明
- -all_load :linker 会将所有可见的文件都载入到静态库中
- -force_load :从 Xcode3.2之后才有的选项,能使得文件的载入更细化,每一个你要载入的文件,都要增加一个 -force_load 选项,并且在 -force_load 后面跟上要导入的文件路径。例如:
-force_load $(BUILT_PRODUCTS_DIR)/<library_name.a>
使用 -all_load 会导致很多多余文件的导入,会导致静态库体积变大;
使用 -force_load 会很麻烦,要一个个手动添加,但是针对性强。我选择的是这个。
3.在你的category的实现文件开头写一个空的class,来避免在 iOS 中使用 -ObjC 的 linker 的 bug。但是记住,还是需要把使用静态库的 Target 中的 Building Setting 的 Other Linker Flags 设置成 -ObjC 。
关于方案的选择,这要因人而异了。
(iOS)谈谈关于使用category的静态库(原创)的更多相关文章
- iOS——为Xcode编译POCO C++静态库
一.POCO C++ library简介 POCO C++ library是一个C++编写的跨平台库,主要实现网络连接.数据库管理以及服务器,适用于跨平台.嵌入式. 二.为Xcode编译POCO C+ ...
- iOS 在工程内部创建一个静态库target
当你在开发项目的时候需要把公用的东西打包出来,其他项目方便使用的时候,打包成静态库是你的最优选择,在工程内部开发的时候新建一个target进行静态库的开发可以使你的开发调试更加方便而不是单独新建一个工 ...
- [IOS 静态库]
http://www.2cto.com/kf/201402/276718.html 一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷 ...
- 【转】iOS静态库 【.a 和framework】【超详细】
原文网址:https://my.oschina.net/kaqijiang/blog/649632 一.什么是库? 库是共享程序代码的方式. 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存 ...
- IOS静态库和Framework区别
一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...
- iOS基础 - 静态库
一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...
- iOS 静态库,动态库与 Framework 浅析
静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...
- IOS .a静态库的和.framework制作
什么是库? 库是程序代码的集合,是共享程序代码的一种方式 根据源代码的公开情况,库可以分为2种类型 开源库 公开源代码,能看到具体实现 比如SDWebImage.AFNetworking 闭源库 不公 ...
- (转)iOS静态库与动态库的区别
一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...
随机推荐
- Error: Cannot find module 'gulp-clone'问题的解决
安装完gulp环境,并且配置好gulpfile.js,执行静态文件压缩和代码混淆时,出现如下错误: Error: Cannot find module 'gulp-clone' Error: Cann ...
- centos7搭建nexus maven私服
前置条件: 1.安装jdk,可参考 http://www.cnblogs.com/grey-wolf/p/6480489.html 2.nexus仓库管理器,分为两个版本,Nexus Reposito ...
- EWS 通过SubscribeToPullNotifications订阅Exchange新邮件提醒
摘要 在ews中提供了一种拉通知的方式获取服务端邮件的操作,通过这种方式客户端可以订阅该通知,在邮箱有变化的时候,可以收到通知. 工作方式 EWS 通知是在订阅的基础上处理的.通常是一个订阅每个邮箱, ...
- 用JS常规方法是否离开当前页面
该方法在 关闭页面时 会提示 <script type="text/javascript"> var DispClose = true; function CloseE ...
- 用php做省份的三级联动 附带数据库
可以把它做成小插件的形式,以后需要,可以随时调 来看一下怎么来做 先来写个div然后,再引入js包 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...
- 项目架构开发:数据访问层之UnitOfWork
接上文 项目架构开发:数据访问层之IQuery 本章我们继续IUnitOfWork的开发,从之前的IRepository接口中就可以看出,我们并没有处理单元事务, 数据CUD每次都是立即执行的,这样有 ...
- 数字化工厂ERP解决方案
数字化工厂 数字化工厂建设,在现有基础上提升,实现管理层对订单进度.生产绩效.产能分析.质量管理.产品追溯和存货管理等提供业务分析报告:在控制层有可视化看板.移动客户端实现对生产状态的实时掌控,快速处 ...
- Spring RESTful + Redis全注解实现恶意登录保护机制
好久没更博了... 最近看了个真正全注解实现的 SpringMVC 博客,感觉很不错,终于可以彻底丢弃 web.xml 了.其实这玩意也是老东西了,丢弃 web.xml,是基于 5.6年前发布的 Se ...
- 如何更新 OpenStack 组件?- 每天5分钟玩转 OpenStack(161)
这是 OpenStack 实施经验分享系列的第 11 篇. 本节教大家更新 OpenStack 组件的方法.请注意,是更新(Update)而不是升级(Upgrade).更新是给组件打补丁,版本不变:而 ...
- [LeetCode]Rotate Image(矩阵旋转)
48. Rotate Image Total Accepted: 69437 Total Submissions: 198781 Difficulty: Medium You are give ...