概述
OC对象的分类
OC对象主要分为三种
- instance对象(实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
instance对象
instance对象就是通过类alloc
出来的对象,每次调用alloc
都会产生新的instance对象
// object1、object2是NSObject的instance对象(实例对象)
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];
// 通过打印可以看出,它们是不同的两个对象,分别占据着两块不同的内存
NSLog(@"instance - %p %p",
object1,
object2);
instance对象在内存中存储的信息
- isa指针
- 其他成员变量的具体值
class对象
每个类在内存中有且只有一个class对象
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1);
Class objectClass4 = object_getClass(object2);
Class objectClass5 = [NSObject class];
// 通过打印可以看出,上面几个方法返回的都是同一个类对象,内存地址都一样
NSLog(@"class - %p %p %p %p %p %d",
objectClass1,
objectClass2,
objectClass3,
objectClass4,
objectClass5);
注意: class方法返回的一直是类对象,所以哪怕这样写还是会返回类对象
Class objectMetaClass2 = [[[NSObject class] class] class];
class对象在内存中存储的信息
- isa指针
- superclass指针
- 类的属性信息(@property)、类的对象方法信息(instance method)
- 类的协议信息(protocol)、类的成员变量信息(ivar)
- …
meta-class对象
objectMetaClass是NSObject的meta-class对象(元类对象),每个类在内存中有且只有一个meta-class对象
Class objectMetaClass = object_getClass(objectClass5);
meta-class对象和class对象的内存结构是一样的,但是用途不一样,在内存中存储的信息主要包括
- isa指针
- superclass指针
- 类的类方法信息(class method)
- …
使用class_isMetaClass(Class _Nullable cls)
来查看Class是否为meta-class 的方法
NSLog(@"objectMetaClass - %p %d", objectMetaClass, class_isMetaClass(objectMetaClass));
注:meta-class对象和class对象的内存结构是一样的,以上两者相比对方没有列出的信息对应的值其实是null
isa和superclass
这里有一个经典的图,精辟描述了 实例对象、类对象、元类对象、isa、superclass 之间的关系
instance通过isa找到class, class通过isa找到meta-class, 所有meta-class的isa都指向 基类的meta-class, 而基类的meta-class的 isa 指向自己
子类的 superclass 指向父类, 直到基类(NSObject),而基类的 superclass 指向nil
子类的元类的 superclass 指向父类的元类, 直到基类(NSObject)的元类, 而基类的元类的 superclass 指向 基类
Tip:
所以如果调用一个基类没有实现的类方法,即基类的元类中没有存储该类方法, 会去基类中找方法名一致的对象方法
OC是面向对象的 对象调用方法 就等于 给对象发送消息 objc_msgSend
中传入的是方法名, 没有带上 +
-
符号
//消息由接受者,selector及参数构成。给某对象“发送消息”也就相当于在该对象上调用方法。
id returnValue = objc_msgSend(someObject,@selector(messageName:),parameter);
总结如下:
每个类的实例对象、类对象、元类对象都有一个isa指针
- instance的isa指向class
- 当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用
- class的isa指向meta-class
- 当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用
- meta-class的isa指向基类的meta-class
每个类的类对象、元类对象都有一个superclass指针
- class的superclass指针指向父类的class
- 如果没有父类,superclass指针为nil
- meta-class的superclass指向父类的meta-class
- 基类的meta-class的superclass指向基类的class
instance调用对象方法的轨迹
- isa找到class,方法不存在,就通过superclass找父类
class调用类方法的轨迹
- isa找meta-class,方法不存在,就通过superclass找父类
最后
以上就是完美自行车为你收集整理的【iOS】通过OC类的本质初探OC方法调用的全部内容,希望文章能够帮你解决【iOS】通过OC类的本质初探OC方法调用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复