iOS开发高手课
戴铭
前滴滴出行技术专家
立即订阅
11464 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 锚定一个点,然后在这个点上深耕
免费
基础篇 (20讲)
01 | 建立你自己的iOS开发知识体系
02 | App 启动速度怎么做优化与监控?
03 | Auto Layout 是怎么进行自动布局的,性能如何?
04 | 项目大了人员多了,架构怎么设计更合理?
05 | 链接器:符号是怎么绑定到地址上的?
06 | App 如何通过注入动态库的方式实现极速编译调试?
07 | Clang、Infer 和 OCLint ,我们应该使用谁来做静态分析?
08 | 如何利用 Clang 为 App 提质?
09 | 无侵入的埋点方案如何实现?
10 | 包大小:如何从资源和代码层面实现全方位瘦身?
11 | 热点问题答疑(一):基础模块问题答疑
12 | iOS 崩溃千奇百怪,如何全面监控?
13 | 如何利用 RunLoop 原理去监控卡顿?
14 | 临近 OOM,如何获取详细内存分配信息,分析内存问题?
15 | 日志监控:怎样获取 App 中的全量日志?
16 | 性能监控:衡量 App 质量的那把尺
17 | 远超你想象的多线程的那些坑
18 | 怎么减少 App 电量消耗?
19 | 热点问题答疑(二):基础模块问题答疑
20 | iOS开发的最佳学习路径是什么?
应用开发篇 (12讲)
21 | 除了 Cocoa,iOS还可以用哪些 GUI 框架开发?
22 | 细说 iOS 响应式框架变迁,哪些思想可以为我所用?
23 | 如何构造酷炫的物理效果和过场动画效果?
24 | A/B 测试:验证决策效果的利器
25 | 怎样构建底层的发布和订阅事件总线?
26 | 如何提高 JSON 解析的性能?
27 | 如何用 Flexbox 思路开发?跟自动布局比,Flexbox 好在哪?
28 | 怎么应对各种富文本表现需求?
29 | 如何在 iOS 中进行面向测试驱动开发和面向行为驱动开发?
30 | 如何制定一套适合自己团队的 iOS 编码规范?
31 | iOS 开发学习资料和书单推荐
32 | 热点问题答疑(三)
原理篇 (6讲)
33 | iOS 系统内核 XNU:App 如何加载?
34 | iOS 黑魔法 Runtime Method Swizzling 背后的原理
35 | libffi:动态调用和定义 C 函数
36 | iOS 是怎么管理内存的?
37 | 如何编写 Clang 插件?
38 | 热点问题答疑(四)
原生与前端共舞 (5讲)
39 | 打通前端与原生的桥梁:JavaScriptCore 能干哪些事情?
40 | React Native、Flutter 等,这些跨端方案怎么选?
41 | 原生布局转到前端布局,开发思路有哪些转变?
42 | iOS原生、大前端和Flutter分别是怎么渲染的?
43 | 剖析使 App 具有动态化和热更新能力的方案
用户故事 (1讲)
用户故事 | 我是如何学习这个专栏的?
结束语 (1讲)
结束语 | 慢几步,深几度
iOS开发高手课
登录|注册

05 | 链接器:符号是怎么绑定到地址上的?

戴铭 2019-03-21
你好,我是戴铭。
你是不是经常会好奇自己参与的这么些项目,为什么有的编译起来很快,有的却很慢;编译完成后,有的启动得很快,有的却很慢。其实,在理解了编译和启动时链接器所做的事儿之后,你就可以从根儿上找到这些问题的答案了。
所以,在今天这篇文章中,我就重点和你讲解一下链接器相关的知识。简单地说,链接器最主要的作用,就是将符号绑定到地址上。理解了这其中的原理后,你就可以有针对性地去调整和优化项目了。
同时,掌握了链接器的作用,也将有助于你理解后面文章中,关于符号表、加载相关的内容。
现在,我们就从 iOS 开发的起点,也就是编写代码和编译代码开始说起,看看链接器在这其中到底发挥了什么作用。

iOS 开发为什么使用的是编译器?

我们都知道,iOS 编写的代码是先使用编译器把代码编译成机器码,然后直接在 CPU 上执行机器码的。之所以不使用解释器来运行代码,是因为苹果公司希望 iPhone 的执行效率更高、运行速度能达到最快。
为什么说用解释器运行代码的速度不够快呢?这是因为解释器会在运行时解释执行代码,获取一段代码后就会将其翻译成目标代码(就是字节码(Bytecode)),然后一句一句地执行目标代码。
也就是说,解释器,是在运行时才去解析代码,这样就比在运行之前通过编译器生成一份完整的机器码再去执行的效率要低。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《iOS开发高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(55)

  • 陈栋楠
    《程序员的自我修养》里有非常详细的关于链接的内容,对于想学习这块知识的同学是很好的资料
    2019-03-29
    11
  • 邓斌
    我发现戴大神写几篇的主题跟我最近在写的博客很像哦哈哈ヾノ≧∀≦)o
    https://www.jianshu.com/p/95896fb96a03

    作者回复: 写的真棒,赞

    2019-03-21
    10
  • 绝影
    太棒了,有料。深入浅出,文末还有总结,支持这样文章结构!
    2019-03-21
    5
  • 石年
    这里系统上的动态链接器会使用共享缓存,共享缓存在 /var/db/dyld/。当加载 Mach-O 文件时,动态链接器会先检查是否有共享缓存。每个进程都会在自己的地址空间映射这些共享缓存

    我有个问题,是不是在动态加载的时候对于公用的动态库还是得在内存做拷贝,保证进程间相互隔离?如果进程地址空间映射方式共享,我在A应用用fishhook去hook一个公用动态库,那是不是会影响所有用到这个公用动态库的其他应用,实验证明只会影响自身应用。大神帮忙解释下~_~
    2019-04-28
    3
    4
  • straycandy
    你好,请问下oc具有动态特性,链接器在清理无用函数时候,如何保证运行时不会指向这个函数呢?比如页面路由之类的函数,函数名都是拼接而成的。很是疑惑,而且经过实验,链接器确实辨认出来了这些函数,开启dead code stripping 后没有导致崩溃

    作者回复: oc 的不会,c 的会

    2019-04-05
    4
  • smilingmiao
    老师,经过我的实践,你的 -show 应该改成 --show。

    作者回复: 赞

    2019-03-22
    4
  • 晓龙
    看到动态绑定,大概了解了下flutter调试时是如何hotreload UI的。

    flutter有两套编译器,JIT,AOT。
    debug时用JIT,release时AOT。

    debug时,如果修改了dart文件,按下R后,Dart会先去工程里遍历增量dart源文件,然后通知Dart VM去load改写后的dart文件,通知flutter framework去更新widgets tree。

    参考:https://www.jianshu.com/p/69c96cefc810?tdsourcetag=s_pctim_aiomsg
    2019-03-21
    4
  • mαnajay
    这里的共享缓存是 [Diving into WWDC 2017] App Startup Time: Past, Present, and Future 里面说的 Dyld 2.0 开始引入的 prebinding completely replaced by shared cache 吗? 用来进程间共享这块系统的动态库 相关地址信息

    作者回复: 对

    2019-03-23
    3
  • Trust me ҉҉҉҉҉҉҉❀
    dyld3可以预绑定系统库的 符号 加快启动时间
    2019-03-21
    3
  • langzuxiaozi
    dlopen dlsym 审核会被拒,是有办法解决这个问题吗?
    2019-03-21
    1
    3
  • 不知名的iOS网友
    dyld 编译不通过的原因:
    估计大家都是直接复制的代码,由于文本的问题,#import "xxx.h" ,""这个英文字符已经被替换成了中文字符,所以大家更改一下就能编译通过啦。
    2019-04-30
    2
  • Eric
    老师请问下 既然Mach-o中清理掉了没用的函数 那废弃的函数不用删除也不会影响包大小,那删除没用的函数来达到瘦身效果的说法就不正确了对吧 ,被用到的函数中的无用代码才会影响包大小这样理解对嘛
    2019-03-30
    2
  • hao
    老师你好
    使用 dyld 加载动态库,有两种方式:有程序启动加载时绑定和符号第一次被用到时绑定。
    请问这个可以在哪里设置的吗?
    2019-03-26
    2
  • zeroskylian
    在 App 运行时通过 dlopen 和 dlsym 链接加载 bundle 里的动态库。

    这个是不是只能用于调试,记得iOS不允许在沙盒中加载动态库

    作者回复: 是的,用于调试

    2019-03-21
    2
  • springday
    老师,iOS目前支持AOT么。另外,感觉iOS目前编辑时间过长,是不是应该采用flutter的预编辑机制呢。

    作者回复: 期待苹果爸爸赶快加上吧

    2019-03-21
    2
  • 난너하나만
    再比如,你可以逆向找出其他 App 里你感兴趣功能的使用方法,然后在自己的程序里直接调用它,最后将那个 App 作为动态库加载到自己的 App 里。这样,你感兴趣的这个功能,就能够在你自己的程序里起作用了。


    这需要越狱机吧?

    作者回复: 是的

    2019-03-21
    2
  • Geek__Will
    符号绑定是否只对类做符号绑定?不会对方法或者变量做绑定?在静态库中在oc类文件.m中如果有定义的c或者c++的函数或者变量,默认会是全局的,而且会绑定地址,如果两个相同静态库定义了同名的函数或者变量,link如果加了-ObjC会报重复定义的冲突,如果没加,则编织通过,且不影响运行,麻烦老师给讲讲原理,谢谢
    2019-04-23
    1
  • 陈希敏
    老师请问一下,在 load_images 方法里断点 p path,这一步是怎么做的?

    作者回复: 你先拉 https://github.com/RetVal/objc-runtime ,搜素 load_images 方法,在那里打断点

    2019-04-10
    1
  • 爱弹吉他的纳兰沛容
    老师,我有个疑问:OC是编译语言,Xcode使用的是LLVM编译器,那么生成的ipa包应该是经过编译后的机器码,所以在iOS系统内是不存在编译器的,而安卓系统则存在JVM虚拟机?

    作者回复: 对

    2019-03-31
    1
  • Hjay
    每个文件编译出来的mach-o文件类型是目标文件吧,走过link才会聚合成mach-o可执行文件

    作者回复: 对

    2019-03-28
    1
收起评论
55
返回
顶部