OC的方法调用:消息机制,给方法调用者发送消息
消息发送
动态方法解析
要注意:
消息转发
将消息转发给别人
元类对象的消息转发
super
调用super的结论:
super调用的消息接收者仍然是子类对象,只不过是从父类的类对象开始去搜索方法.
class方法的底层实现是object_getClass(self),谁调用这个方法就返回谁的类型,虽然看起来是[super class],但是还是self在调用,因为消息接收者是self,写super只是从父类开始查找class方法,但实际调用和接收这个方法的还是self.
这里有一个概念方法调用者就是消息接收者
本质是
1:两个找的class方法的方法实现是一样的
2:消息接收者都是self,所以结果一样
首先把self传进去看当前类型是什么类型,把当前类型传进去再告诉你父类是什么类型,还是取决于消息接收者是谁
消息转发用途
不会报方法找不到的错误导致crash,尝试收集一下没有实现方法的信息,可以知道哪个方法没有实现
可以给NSObject写一个分类.想统一拦截.
isMemberOfClass, isKindOfClass
isMemberOfClass是判断是否刚好等于参数类型
isKindOfClass判断是否是参数类型或者参数类型的子类
类方法中判断MJPerson类对象她的object_getClass(MJPerson)是元类对象,并不是[MJPerson class].
实例对象的类对象是类对象
类对象的类对象是元类对象
不管是对象方法还是类方法原理是一样的
person的isa指向的类对象是否刚好等于传进来的对象.
MJPerson这个类的isa指向的元类对象是否等于传进来的对象
子类的元类对象通过superClass拿到父类的元类对象,一直一直调就会拿到基类的元类对象,基类的superclass是指向基类的类对象即[NSObject class].
判断
1:[NSObject isMemberOfClass:[NSObject class]]; //0
NSObject的元类不等于类对象[NSObject class]
2:[NSObject isKindOfClass:[NSObject class]]; //1
判断NSObject的元类一层层往上找superclass会找到NSObject的类对象是等于类对象[NSObject class]
总结
self指对象本身, [self class]返回的是类, 打印出来就相当于类名.
如果想判断某个实例对象是某个类或者某个类型的子类,那么左边如果是实例对象,右边传类对象
如果想判断某个类对象是某个类或者某个类型的子类,那么左边如果是类对象,右边传元类
如果是实例方法,会发现底层是拿类对象[self class]跟传进来的参数比较;
如果是+开头的话,会发现底层是拿元类对象(object_getClass(self))跟创进来的参数比较
栈空间分配问题
看下面代码为何能调用
为什么打印的结果是my name is 123.
person指针指向MJPerson这块内存即isa,
这个考点是
1:super 调用的本质,第一个参数要传一个结构体;
2:函数栈空间分配问题从高地址到低地址;
3:消息机制,调用方法的时候[obj print]要找到isa这个指针;
4:访问成员变量的本质,找到对象的那块内存里面的某一个成员_name,成员变量是结构体中的成员,每一个实例对象的本质都是一个结构体,所以找实例对象的成员变量,其实是找结构体的成员,找结构体的成员,就是跳过前面isa找到下一个成员
super底层