最近在一个项目中使用了一个包含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的静态库(原创)的更多相关文章

  1. iOS——为Xcode编译POCO C++静态库

    一.POCO C++ library简介 POCO C++ library是一个C++编写的跨平台库,主要实现网络连接.数据库管理以及服务器,适用于跨平台.嵌入式. 二.为Xcode编译POCO C+ ...

  2. iOS 在工程内部创建一个静态库target

    当你在开发项目的时候需要把公用的东西打包出来,其他项目方便使用的时候,打包成静态库是你的最优选择,在工程内部开发的时候新建一个target进行静态库的开发可以使你的开发调试更加方便而不是单独新建一个工 ...

  3. [IOS 静态库]

    http://www.2cto.com/kf/201402/276718.html 一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷 ...

  4. 【转】iOS静态库 【.a 和framework】【超详细】

    原文网址:https://my.oschina.net/kaqijiang/blog/649632 一.什么是库? 库是共享程序代码的方式. 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存 ...

  5. IOS静态库和Framework区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...

  6. iOS基础 - 静态库

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 二.静态库与动态库的区别? 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系 ...

  7. iOS 静态库,动态库与 Framework 浅析

    静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...

  8. IOS .a静态库的和.framework制作

    什么是库? 库是程序代码的集合,是共享程序代码的一种方式 根据源代码的公开情况,库可以分为2种类型 开源库 公开源代码,能看到具体实现 比如SDWebImage.AFNetworking 闭源库 不公 ...

  9. (转)iOS静态库与动态库的区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...

随机推荐

  1. SuperWebClient -一个基于CURL的.NET HTTP/HTTPS模拟神组件(1)

    我们都知道,不管你是做爬虫也好,采集工具也罢,它们的HTTP/HTTPS模拟访问总是一个基础问题,我估计有很多人和我一样,虽然这样,那样的内置或是第三方类库用了很多,却总是会有一些不如意的问题存在,亦 ...

  2. 2017-3-2 C#基础 结构体

    1. 结构体:用户自定义类型定义位置:定义在Main函数的外面,类的里面 定义格式:struct 自定义名字{ public 数据类型 名字; public 数据类型 名字; ... ...} 声明实 ...

  3. JDK 安装过程

    1.首先是下载jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.下载完 ...

  4. Apache Struts2存在S2-045

    麻蛋的,批了老半天都找不到,还得谷歌 不扯蛋了,直接主题: Struts2 2.3.32 版本 下载地址:https://dist.apache.org/repos/dist/release/stru ...

  5. 写lua时需要注意的地方

    条件语句判断时,只有false和nil会导致判断为假,其他的任何值都为真. Lua 的字符串与编码无关: 它不关心字符串中具体内容. 标准 Lua 使用 64 位整数和双精度(64 位)浮点数, 但你 ...

  6. Maximum Depth of Binary Tree leetcode

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. MyEclipse下打开ftl文件

      转:http://blog.csdn.net/w410589502/article/details/51669028 1.Freemarker模板的文件后缀名 2.Freemarker其实是一种比 ...

  8. 最短路径之Dijkstras算法(图片格式)

  9. Android自学反思总结(上)

    从接触Android到现在有几个月的时间了,基本全部都是靠自学,从大一上学期学习完c语言,接着利用寒假时间和开学一个月左右的时间自学完javase,接着在导员的督促下,开始了Android学习之旅,现 ...

  10. 关于npm安装全局模块,require时报Error: Cannot find module 'XXX'的解决办法

    系统环境:centos 下午使用npm安装"cheerio",想搞爬虫玩玩. npm安装有两种模式: 本地 # npm install cheerio 全局 # npm insta ...