Objective-C super
在OC中调用方法有两个默认参数,self和_cmd。所以我们可以在方法中直接使用该参数。而super不是参数而是一个编译器标识符,告诉OS到调用父类的方法。
关于super的调用规则请看下图;图片来源这儿
例如:
[self doSomething];
从当前类中查找doSomething,没有找到在到父类中查找,以此类推;注意NSObject的superclass是nil。
[super doSomething];
从父类中查找doSomething,然后再到父类的父类中查找,以此类推;注意基类的superclass是nil。
现在提出一个问题
@interface myClass : NSObject
@end
@implementation myClass
-(instancetype)init{
self = [super init];
if (self) {
Class selfClass = self.class;
Class superClass = super.class;
Class selfSuperClass = self.superclass;
Class superSuperClass = super.superclass;
}
return self;
}
@end
为了搞清楚selfClass,superClass,selfSuperClass,superSuperClass是那个类首先要了解消息机制。
当使用self的时候消息机制调用是:
objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
第一个参数是 self 第二个参数是方法选择器, 其他是参数
使用super时候消息机制调用是:
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
第一个参数是 objc_super 第二个参数是方法选择器, 其他是参数
struct objc_super * _Nonnull super中的objc_super struct的结构是:
struct objc_super {
id receiver;
Class super_class;
};
通过指令 clang -rewrite-objc myClass.m 编译可以看到:
Class superClass = ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Person"))}, sel_registerName("class"));
objc_super 的成员 receive 是 self。
所以 self.class和super.class实际调用对象都是self,super.class是相当于self.class 就是myClass 而super.superclass是NSObject而不是nil。
个人知识点记录