更新记录
时间 | 更新记录 |
---|---|
2020年4月6日 | 初稿 |
前言
- iOS的对象模型,在《Objective-C基础教程》第2版 4.3-继承的工作机制中,用了一两页的篇幅来说明,而且很简单,易于理解。
- 而笔者特地写下这一篇文章,是因为这个知识点,是OC开发的基础。所谓基础不牢,地动山摇。先把最基础的知识点学透,总结好,再逐渐地一点点刨深入的细节。
- 不同于之前写的C++对象模型学习,这里不会有若干种对象模型的对比。直接拍出当前Objective-C的对象模型。
iOS对象模型
对象内存布局
- OC中的对象都继承于NSObject,它们和C++对象类似,实例变量(C++里就叫成员变量)都存在于对象的内存之中。
- 由于OC中没有虚函数的概念,所以并没有所谓的“虚函数指针”
- 基类到子类的实例变量依次排列。由于OC对象都继承于NSObject,所以对象的第0个偏移量对应的就是isa指针。
- 举《Objective-C基础教程》第2版 4.3-继承的工作机制中的例子,继承链为:RoundedRectangle---->Shape----->NSObject。RoundedRectangle对象的内存模型如图:
方法调度机制
- 众所周知,在OC调用一个对象的方法(C++就叫成员函数罗),其实就是给这个对象发消息(
objc_msgSend
) - 对象的方法列表存储在【isa指针指向的类对象】中
- 类的类方法列表(C++里面就叫静态成员函数)存储在元类(元类就是类对象的isa指针指向的对象)对象中
- 举《Objective-C基础教程》第2版 4.3-继承的工作机制中的例子,生成的对象的方法列表:
对象、类对象、元类对象的关系
-
这里主要是参考iOS底层原理总结 - 探寻OC对象的本质,盗一张图,简洁果断地说明三者的关系
-
和C++的比较
- 优点
- 增加了灵活性和便捷性
- 缺点
- 调用方法(
C++
里面叫成员函数)比C++
慢的多,因为需要遍历方法列表,查找到相应的方法实现。 - 不如
C++
安全。因为C++
的编译器和连接器可以确保对象能够处理对应的方法。而Obejctive-C中,如果被发送消息的对象不能处理该消息,就会得到运行时错误。(unrecognized selector sent
运行时错误,写过一段时间OC代码的同行应该都遇到过)
- 调用方法(
- 优点
参考资料
- 《Objective-C基础教程》第2版 4.3-继承的工作机制
- 《Objective-C基础教程》附录 A.3 C++虚拟表与Objective-C动态分类
- iOS底层原理总结 - 探寻OC对象的本质
- cnblogs文章/MarkDown内如何调整图片的宽度?