写在前面
开发了3年的iOS了,虽然接触了许多七七八八的东西、技术,但是感觉iOS却没有什么质的飞越,可能跟自己接触的项目深度有关,于是决定在学习其他技术的同时,加强自己在iOS方面的学习,提高自己的竞争力。
这里以MJ老师的底层视频,写出自己对学习底层原理理解
对象&类对象&元类对象(Object & Class & Meta Class)
实例对象(Object) : 例如 NSObject *obj =[[NSObject alloc] init]
,创建出来的就是一个实例对象,实例对象记录着实例对象的isa
指针和其他成员变量等
类对象 (Class) : 类的本质也是一个对象,就是类对象,通过Class objClass = [NSObject class]
可以获得类对象,类对象由编译器生成,记录着类的对象方法
和类对象的isa
指针和superClass
指针以及其他成员变量等
元类对象 (Meta Class): 元类是对类的描述,记录着类的类方法以及isa
指针和superClass
指针等
类对象
和元类对象
在内存中的结构是一样的
验证对象存储内容
我们打开obj4
源码(obj4源码可在day1查看下载方式),搜索objc_class
探索类对象的结构体,我们发现
9C35B84C-CDBE-4360-830E-A70EA3E5F12A.png
15F63C61-407F-4844-806A-4912F5DED6F2.png
C9694A62-EB72-4096-BFDE-7689D045329D.png
objc_class
继承自 objc_object
存储着isa
、superclass
、cache
、bits
,而bits
通过位运算可以获得表class_rw_t
,其中包含着methods
(方法)、properties
(属性)和protocal
等,而class_rw_t
表又存储着 class_ro_t
表,class_ro_t
表存储着name
(类明),ivars
(成员变量)等信息
最后用一张图来总结类对象的结构体存储
E14EE981-F081-4E38-A5A0-1E6EC68DAEF3.png
isa
10557ADD-8CAA-4FC5-A734-6B2BB0E83EB6.png实例对象isa
指向类对象
当我们创建一个对象,并要调用他的对象方法,但是实例对象的对象方法是存储在类对象里面,而我们调用对象方法实际上是给对象发送消息,如果实例对象和类对象没有什么关联的话,最终方法是没办法调用成功的,所以这里isa
是指向类对象(我们可以这样记忆实例对象的isa
)
例如 :
这里,student
调用 studentInstanceMethod
对象方法,是通过student
的isa
指针,找到student
类对象所存储的对象方法执行
类对象isa
指向元类对象
同理,由于类方法存储在元类对象内,而我们调用类方法isa
指向元类对象,才能执行类方法
这里,
Student
调用 studentClassMethod
对象方法,是通过Student
的isa
指针,找到Student
元类对象所存储的类方法执行
这里我们用一幅图总结isa
在 实例对象 & 类对象 & 元类对象的指向
isa
扩充
在64位系统下isa
并不是直接存储指向的对象地址,而是需要位运算(&)
ISA_MASK
__arm64__
: iOS
64位系统
__x86_64__
: Mac
64位系统
Superclass
子类的类对象Superclass
指向父类的类对象
如图
A806D728-E2C1-40AB-BCDC-E7EA4181910E.png
Student
调用父类Person
的类方法,首先Student
通过本身的isa
指针找到Student
元类对象,发现没有personClassMethod
方法,便去Person
元类对象找,这时候就需要通过Student
的Superclass
指针,才能找到Person
元类对象,并调用方法
我们用一幅图来总结Superclass
的指向
Tip
Superclass
就是直接指向父类的内存地址值
总结
我们用一幅图总结isa
和Superclass
的指向
网友评论