前言
这篇文章是在学习原理前,梳理思路,为了规划所写的
在AI时代,关于原理的学习不应该只注重于是否知道原理,而要更深刻的理解语言原理背后的设计哲学,以及设计思路
这门语言解决的核心问题是什么?
它的设计思路是什么?(为什么这样设计而不是那样设计?)
它的trade-off是什么?(获得了什么,牺牲了什么?)
它在什么条件下会失效?
再向外扩展:
Python 为什么被设计成这样?Guido van Rossum 当年做了哪些取舍,放弃了什么,才换来了今天这个”慢但好用”的局面?
同样的问题可以问所有语言:C++为什么搞得这么复杂?JavaScript 为什么满地都是坑?Rust 为什么逼着你和编译器吵架?Go为什么死活不肯加泛型(后来又加了)?
把这些问题串起来,你会发现一件事——今天所有主流编程语言的样子,都不是某个天才拍脑袋的产物,而是七十年来无数次设计博弈的累积结果。
完成了这些问题的学习,所谓的最佳实践就不再需要记忆了
因为你可以根据具体场景自己推导出最合适的方案
那些规范的“最佳实践”(在你的业务逻辑里不一定是最佳)不再是你死记硬背的教条,而是你自己也能想到的自然选择
1. 老前辈们的设计
由于对其他语言的需求不高,所以这里只是简单引用别人的话来展示这段历史
我们从对象的始祖语言开始讲起,即:Simula 67(1967)
Simula 67 (1967)
Simula 67(1967)Ole-Johan Dahl 和 Kristen Nygaard 在奥斯陆研究船舶仿真,发现 Fortran 和 Algol 根本无法优雅地描述"一个对象在现实世界中的行为"。他们在 Algol 60 的基础上引入了 class、对象实例、继承、虚函数——历史上第一门面向对象语言就此诞生。牺牲的是工业落地能力:Simula 是封闭的全栈仿真环境,没法复用已有代码库,性能也不够贴近硬件,工程界难以大规模采用
Smalltalk (1972)
Smalltalk(1972)Alan Kay 在施乐 PARC 读到 Simula 后深受震撼,但觉得还不够彻底。他的灵感来自生物学——细胞通过化学信号通信,而不是直接操作对方内部结构。Smalltalk 把这个比喻做到了极致:万物皆对象,一切皆消息传递,连
if-else都不是关键字,而是向布尔对象发消息。它还发明了图形化 IDE 和实时编译环境。牺牲的同样是是工程实用性:Smalltalk 也是个封闭的全栈世界,没法复用 C 的代码库,性能也无法满足系统级开发,注定只能活在研究院里
Objective-C (1984)
Objective-C(1984)Brad Cox 面对一个两难困境:Smalltalk 的对象模型太美,但是封闭世界,没法复用 C 的代码库;C 的代码库浩如烟海,但没有面向对象的组织能力。他的解法不是重新发明轮子,而是把两个轮子焊在一起——C 的部分原封不动,Smalltalk 的消息传递语法用方括号
[receiver message]原样搬进来,两套系统并存互不干涉。NeXT 和后来的苹果用它构建了整个平台,统治苹果生态将近三十年。牺牲的是统一性:OC 本质上是两门语言的拼接,两套心智模型并存,加上头文件分离和早期的手动内存管理,整体显得繁琐而割裂
Swift (2014)
Swift(2014)Chris Lattner 造 Swift,是在回答一个问题:如果今天从零开始,不背着历史包袱,一门面向苹果平台的语言应该长什么样?他从 Haskell、ML 借来类型推断和不可变性,从 Rust 借来值类型优先,从 Go 借来协议的简洁性,内存管理沿用 ARC 保持性能可预测,同时强迫开发者正视空值问题。没有头文件,没有指针运算,没有未定义行为。牺牲的是早期稳定性——Swift 1 到 Swift 3 语法剧烈变动,老代码经常无法编译,快速迭代的代价全部转嫁给了当时的开发者
阅读语言的开发由来能更好的让我们理解代码,明白OC为什么这样设计,它想解决的问题是什么,它的缺点又是什么
设计就是取舍,没有免费午餐
2. Objective-C概述
Objective-C的元祖为Smalltalk,并继承了其万物皆对象的理念。
所以Objective-C 以对象为绝对核心,用对象模型奠定整个底层体系的基石——每一个对象都是有血有肉的 C 结构体,isa 指针将实例、类、元类串联成一张有机的网;
在此之上,Runtime 为语言注入动态灵魂,让方法调用在运行时才真正落地,赋予代码在编译期之外仍能自我改变的能力;
内存管理则以引用计数为尺,精确丈量每一个对象该活多久、何时消亡;
Block 作为语言与底层之间的桥梁,以闭包的姿态捕获世界、以对象的身份参与内存,是六大板块中交叉最深的一个;
RunLoop 像一颗不知疲倦的心脏,让线程在事件与休眠之间有节律地跳动,维持着应用持续运转却不空耗资源的平衡;
多线程最终将"时间"这个维度引入体系,以并发的力量提升效率,又以锁与队列驯服随之而来的混乱——六大板块以对象为根,彼此依存、相互咬合,共同撑起 Objective-C 作为一门兼具动态性与系统级深度的语言的完整骨架
对OC原理的学习,也就是对这六大板块的学习
我这里采用目录结构给出总体概览,并在学习之后通过目录来进行自我检测复习
3. Objective-C原理
同之前所说一样,Objective-C可以分为六大模块
由于其万物皆对象的设计,所以从对象模型开始学起,是最好的
这里随着我的博客陆续发布,会填补下面的
所以有的时候你会看到空白的,不要担心,只是我还没发布而已...
3.1 对象模型
对于拥有对象的一门语言来说,
对象模型的实现是很关键的
对于一个对象系统的实现,不妨来这样想:
如果我们要自己建一个对象系统,我们应该考虑什么?
可能我们要考虑这个对象的底层用什么实现
考虑这个对象怎么来向外界表示自己是什么
这个对象的继承链是什么
对象的方法应该如何与对象来进行绑定等等问题
这些问题基本上可以分为几个类型:
内核模块:即对象自己的状态
接口模块:对象对外的契约
协作模块:对象与对象
生态部分:对象与外部世界
对每个类型的设计来说,侧重点都不一样:
- 内核——正确性
- 接口——稳定性
- 协作——清晰性
- 生态——兼容性
以及其实现机制,即贯穿四层的部分,更看重性能
接下来我们从这四个部分来讲解内容
- 本体论,形态,类型,身份——OC的前置策略
- OC对象内核
- OC的对象接口
- OC的对象协作
- OC的对象生态
- OC的实现机制(Runtime 入门)