【iOS系列】聊聊 -ObjC 的故事
"民之失德,乾糇以愆;他山之石,可以攻玉。" - 《诗经》
![](http://apk-pack-public-test.nos.netease.com/59231e018c9849a18ff763c16a895ff6.png?imageView)
在开发 iOS 应用时,可能遇见这样的情况:你想实现的某种功能(比如崩溃收集),已经有成熟的产品提供,可行的方案就是集成这个使用了很久,且有专业人员维护,最重要的是“免费”的产品。一番折腾之后,运行时有可能出现"selector not recognized"错误,最后发现是少了如下的配置(Build Settings -> "-ObjC"):
![](http://apk-pack-public-test.nos.netease.com/45eed87171c24ca8a3d38bfe93495274.png?imageView)
那么这个"–ObjC" 到底是个什么鬼? 我们来扒一扒。
"-ObjC" 的使用场景
据坊间说:如果你集成了有 category 的静态库,有可能出现上述错误。原因就是:Technical Q&A QA1490
"An impedance mismatch between UNIX static libraries and the dynamic nature of Objective-C can cause category methods in static libraries to not be linked into an app, resulting in "selector not recognized" exceptions when the methods aren't found at runtime."
这段话的意思就是:链接器在处理包含Category方法的UNIX的静态库时,没有将Category的方法链接到APP中,造成这个错误。具体的细节在本文的补充部分展开。
可以看出,解决这个错误的方法就是:将Category的方法链接到APP中,这样APP运行时,就能够找到对应的selector。而 –ObjC就可以完成这个任务。
"-ObjC"的作用是:将静态库中任何Objective-C代码都链接到APP中。任何Objective-C代码当然也包括Category的方法。可以看出,使用-ObjC可能会链接很多静态库中未被使用的Objective-C代码,极大的增加APP的代码体积。
"-ObjC" 的兄弟
![](http://apk-pack-public-test.nos.netease.com/1057ffb2d537461ca85504d05b714f53.png?imageView)
和 "-ObjC"作用类似的有以上的五种方案。可以看出,从增加APP代码体积来看,伪符号方案增加得最少"Perform Single-Object Prelink"、 "-force_load" 和 "–ObjC" 次之,"-all_load" 增加得最多。
在开发iOS SDK时,为了方便使用者手动集成,最好是减少使用者需要配置的信息,所以"伪符号"方案和 "Perform Single-Object Prelink"方案是推荐的。另外,第三方SDK常常是闭源的,对于使用者来说,伪符号是透明的,所以从简便性角度看,推荐"Perform Single-Object Prelink"方案。
"selector not recognized"错误的产生根源
iOS工程,从源文件到生成最终的APP文件,通常要经过如下步骤:
![](http://apk-pack-public-test.nos.netease.com/4cfe51db89774e13868ab3db6f2fe6b2.png?imageView)
源文件经过编译和优化后,会生成目标代码。目标代码中包括符号表,标示了此代码中的全局符号和静态符号,还标示了导入符号等,链接器会根据符号表分析各个目标代码之间的调用关系,然后将使用到的代码进行链接和重定位,最后生成可执行文件。
在编译Objective-C源文件到目标文件时,编译器并不知道方法的对应实现,只能在运行时才知道,所以编译器只会为类生成链接符号,对类中的方法不会生成链接符号。由于Category方法并不对应一个新类,所以不会生成链接符号,链接器也不会将Category方法合并到原始的类中,最终导致链接器忽略了Category方法,不会将其链接到可执行文件中。
更多资讯请关注网易云捕微信公众号,网易云捕官方微博~~
参考
1、Technical Q&A QA1490
2、Objective-C categories in static library
【iOS系列】聊聊 -ObjC 的故事相关推荐
- iOS系列教程 目录 (持续更新...)
前言: 听说搞iOS的都是高富帅,身边妹子无数.咱也来玩玩.哈哈. 本篇所有内容使用的是XCode工具.Swift语言进行开发. 我现在也是学习阶段,每一篇内容都是经过自己实际编写完一遍之后,发现 ...
- 【iOS系列】-程序开启后台运行
[iOS系列]-程序开启后台运行 iOS程序是伪后台的运行,可是有时候我们需要让其在后台也要进行一些操作,我们可以让其伪装成音乐的APP,这样就可以让程序后台进行相关操作了,具体做法如下: 1:在Ap ...
- 【iOS系列】-xib封装使用
[iOS系列]-xib封装使用 Xib文件可以用来描述某一块局部的UI界面 Xib文件的加载 修改xib文件的大小size(Freeform) 第一: NSArray *objs = [[NSBund ...
- iOS系列开发-版本控制工具Git的使用
iOS系列开发-版本控制工具Git的使用 作为一个开发者,与团队之间默契的配合是很重要的,我们所写的代码在无论是在公司还是在个人来说都是一份不可随意丢弃的东西,但是如果只是单纯的开发,我们很难做到今天 ...
- 【今晚7点】:圆桌PI回归 继续聊聊开源的故事
点击上方"LiveVideoStack"关注我们 圆桌PI,是LiveVideoStack公开课的形式之一,我们会约上几位专家进行线上的虚拟圆桌讨论,分享观点,探讨热点话题,回答听 ...
- 敏捷开发用户故事系列之五:用户故事的分类
这是敏捷开发用户故事系列的第五篇.(之一,之二,之三,之四,之五,之六,之七,之八,之九) 引子 在之一.之二.之三中,我们曾经提到了"作为一个--可以--以便--"的用户故事描述 ...
- 敏捷开发用户故事系列之七:用户故事与MVC
这是用户故事系列的第七篇.(之一,之二,之三,之四,之五,之六,之七,之八,之九) 用户故事和MVC没有关系,因为MVC是实现方法,因此在思考用户故事的时候,不要一下就想到实现方法,很容易把故事写坏. ...
- 敏捷开发用户故事系列之六:用户故事的产生与组织结构
这是用户故事系列的第六篇.(之一,之二,之三,之四,之五,之六,之七,之八,之九) 一条需求敢跳出来,基本上就能被化成一条用户故事,看完一二三四五,上山打老虎都不怕,这个似乎已经不太难了. 难的是,项 ...
- 敏捷开发一千零一问系列之十三:故事点好还是人天好?
这是敏捷开发一千零一问系列的第十三篇.(在这里提问,之一,之二,之三,问题总目录) 问题 这是课堂上提的一个问题,这是一家外企,PO在国外,研发在国内:PO希望大家用故事点估算,而团队习惯用人天估算, ...
最新文章
- java 视频分辨率_java – Blackberry:如何在录制前设置视频分辨率
- EntLib 3.1学习笔记(6) : Security Application Block
- 计算机接口实验1,计算机接口技术实验一.doc
- 关闭Windows不必要服务,电脑更安全
- C# 索引器使用总结
- leaflet知识整理
- 面向对象 封装 集成 特性
- 脚手架 mixin (混入)
- 【图说word】 宏
- XML文件的读取(XmlParserDemo)
- SQL Server字符串处理函数大全
- 《Qt 5/PyQt 5实战指南》目录
- UTF-8转换成GBK
- html form提交heard,德普前妻Amber Heard戛纳合辑
- win10微软账户无法连接服务器,Win10系统Microsoft微软帐户无法登陆的解决方法
- 医学图像的 有损压缩 以及可接受的 压缩比
- java.nio.Buffer.filp()方法的用法详解
- 【Mybatis-Plus】【异常】Inferred type ‘E‘ for type parameter ‘E‘ is not within its bound;
- 如何实现windows命令提示符的tab补全
- Django入门(一)