(转载)Xcode中other linker flags的作用
原文地址:
https://blog.csdn.net/iosfengguibin/article/details/52086435
今天导入三方的sdk之后,空项目,总是报错“selector not recognized”,在网上找到这篇文章,才解决了问题,感谢作者的分享。
使用场景
在ios开发中,我们经常会使用到第三方的一些静态库,导入第三方类库运行程序后你会发现,编译时可以正常编译但是运行时会app会闪退,报出selector not recognized的错误。一般的第三方库的开发文档中都会写出这种问题的解决方法,如在Other Linker Flags中加入-ObjC或者-all_load或者-force_load这样的解决方法。为什要这要做呢?报错为什么编译的时候有问题呢,首先我们先引入一个链接器的概念.
链接器
还记得我们在学习C程序的时候,从C代码到可执行文件经历的步骤是:
源代码 > 预处理器 > 编译器 > 汇编器 > 机器码 > 链接器 > 可执行文件
在最后一步需要把.o文件和C语言运行库链接起来,这时候需要用到ld命令。源文件经过一系列处理以后,会生成对应的.obj文件,然后一个项目必然会有许多.obj文件,并且这些文件之间会有各种各样的联系,例如函数调用。链接器做的事就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文件
通过这个流程你也应该知道为什么在编译的过程中没事而在运行的时候就会报错了. 那我们为什么要设置Other Linker Flags呢 因为Other Linker Flags其实就是链接器工作时除了默认参数外的其他参数。
闪退的原因
苹果官方Q&A上有这么一段话:
The “selector not recognized” runtime exception occurs due to an issue between the implementation of standard UNIX static libraries, the linker and the dynamic nature of 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.
翻译:运行时的异常时由于静态库,链接器,与OC语言的动态的特性之间的问题,OC语言并不是对每一个函数或者方法建立符号表,而只是对每一个类创建了符号表.如果一个类有了分类,那么链接器就不会将核心类与分类之间的代码完成进行合并,这就阻止了在最终的应用程序中的可执行文件缺失了分类中的代码,这样函数调用接失败了.
other linker flags参数的作用
在前面我们说如果出现问题要在Other Linker Flags中加入-ObjC或者-all_load或者-force_load,我们为什么要加入这样的参数呢,他们究竟做了什么事呢?下面就是对这个三个参数的一个讲解.
ObjC
一般这个参数足够解决前面提到的问题,这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大,因为加载了很多不必要的文件而导致可执行文件变大。但是如果静态库中有类和category的话只有加入这个flag才行,但是Objc也不是万能的,当静态库中只有分类而没有类的时候,Objc就失效了,这就需要使用-all_load或者-force_load了。
-all_load
-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。但是这个参数也有一个弊端,那就是你使用了不止一个静态库文件,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件 这里会有两种方法解决 1:用命令行就行拆包. 2:就是用下面的这个参数
-force_load
这个flag所做的事情跟-all_load其实是一样的,只是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载 .
总结
个人建议ObjC与force_load搭配使用比较好.
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java加密工具类,可设置对应的加解密key
public class AesEncryptUtil { //使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同! private static String KEY ="whshenke20180606"; private static String IV ="whshenke20180606"; /** * 加密方法 * @param data 要加密的数据 * @param key 加密key * @param iv 加密iv * @return 加密的结果 * @throws Exception */ public static String encrypt(String data, String key, String iv) throws Exception { try { Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式" int blockSize = cipher.getBlockSize(); byte[] dataBytes = data.getB...
- 下一篇
十分钟上线-在函数计算上部署基于django开发的个人博客系统
前言 这篇文章适合所有的python开发新手、老鸟以及想准备学习开发python的程序猿。本文以一个基于django开源的个人博客移植到函数计算为例,向您讲解如何使用阿里云函数计算快速构建或移植基于wsgi applicaiton开发的web service。通过本文,您将会了解以下内容: 案例概览 传统服务器架构 VS Serverless架构 Serverless架构详解 案例迁移中存在的问题及解法 案例开发配置步骤 案例概览 在本教程中,我们讲解如何利用函数计算一步一步来构建web的server端,该案例是基于github上一个star很高的一个开源个人博客,在本案例中,不讨论基于wsgi applicaiton的程序开发,本文旨在展示函数计算做web backend 能力,具体表现为以下几点: 完善的基于django搭建的系统迁移到FC的成
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8