iOS对象模型学习

更新记录

时间 更新记录
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代码的同行应该都遇到过)

参考资料

猜你喜欢

转载自www.cnblogs.com/HelloGreen/p/12643659.html