NSObject -> RootCls -> SubCls
@implementation SubCls
- (void)print {
NSLog(@"%@",[self class]);
NSLog(@"%@",[self superclass]);
NSLog(@"%@",[super class]);
NSLog(@"%@",[super superclass]);
}
@end
wrong
answer may look like this:SubCls
RootCls
RootCls
NSObject
SubCls
RootCls
SubCls
RootCls
static void _I_SubCls_print(SubCls * self, SEL _cmd) {
NSLog((NSString *)&__NSConstantStringImpl__var_folders_w4_kn5xrqqn04bcyjv2pkqzv1qr0000gn_T_SubCls_0dc642_mi_0,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_w4_kn5xrqqn04bcyjv2pkqzv1qr0000gn_T_SubCls_0dc642_mi_1,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("superclass")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_w4_kn5xrqqn04bcyjv2pkqzv1qr0000gn_T_SubCls_0dc642_mi_2,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("SubCls"))}, sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_w4_kn5xrqqn04bcyjv2pkqzv1qr0000gn_T_SubCls_0dc642_mi_3,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("SubCls"))}, sel_registerName("superclass")));
}
//The definition of struct `__rw_objc_super`
struct __rw_objc_super {
struct objc_object *object;
struct objc_object *superClass;
__rw_objc_super(struct objc_object *o, struct objc_object *s) : object(o), superClass(s) {}
};
//The definition of struct `objc_object`
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
self
, it will call objc_msgSend
method. While if we call these method with super
it will call objc_msgSendSuper
method, so we can have a depth look at this method://It has two params, one is a struct with type `objc_super *`, and the other is a `SEL`
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
//We can also see the `objc_super *` struct, it contain a receiver and a Class instance.
struct objc_super {
__unsafe_unretained _Nonnull id receiver;
#if !defined(__cplusplus) && !__OBJC2__
__unsafe_unretained _Nonnull Class class;
#else
__unsafe_unretained _Nonnull Class super_class;
#endif
};
#endif
struct __rw_objc_super
as objc_super
and the final code will be like this:objc_msgSendSuper((objc_super){self,class_getSuperclass(objc_getClass("SubCls"))},sel_registerName("class"))
objc_msgSendSuper((objc_super){self,class_getSuperclass(objc_getClass("SubCls"))},sel_registerName("superclass"))
/********************************************************************
* id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
*
* struct objc_super {
* id receiver;
* Class cls; // the class to search
* } ********************************************************************/
ENTRY _objc_msgSendSuper
MESSENGER_START
ldr r9, [r0, #CLASS] // r9 = struct super->class
CacheLookup NORMAL
// cache hit, IMP in r12, eq already set for nonstret forwarding
ldr r0, [r0, #RECEIVER] // load real receiver
MESSENGER_END_FAST
bx r12 // call imp
CacheLookup2 NORMAL
// cache miss
ldr r9, [r0, #CLASS] // r9 = struct super->class
ldr r0, [r0, #RECEIVER] // load real receiver
MESSENGER_END_SLOW
b __objc_msgSend_uncached
END_ENTRY _objc_msgSendSuper
NSObject.mm
which you can download from the apple open source:+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
+ (Class)superclass {
return self->superclass;
}
- (Class)superclass {
return [self class]->superclass;
}
class
and superclass
will make the RootCls
receive the class
and superClass
method, while it don't rewrite the method so it will call the NSObject's
method,and it will have the same result as self
.