iOS分析[self class]和[super class]

Demo

从经典的一个demo开始 。前提:XXSon继承自 XXFather

@implementation XXSon

- (id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class]));
    }
    
return self;
}

@end

打印结果都是 XXSon。

分析

准备工作
  1. 我们知道向对象发送消息最终会转化成objc_msgSend方法,定义如下:
objc_msgSend(void /* id self, SEL op, ... */ )  

第一个参数是接收消息的对象
第二个参数是方法选择器

  1. super关键字接受消息时,会转化成objc_msgSendSuper方法,定义如下
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )

第一个参数是objc_super结构体
第二个参数是方法选择器
objc_super结构体的定义在 message.h文件中, 现在都是OBJC2,简化后定义如下:

/// Specifies the superclass of an instance. 
struct objc_super {
   /// Specifies an instance of a class.
   __unsafe_unretained _Nonnull id receiver;
   __unsafe_unretained _Nonnull Class super_class;
   /* super_class is the first class to search */
};

super关键字表示让直接从super_class中开始查找方法的实现。

  1. Demo中的XXSon.m经过clang -rewrite-objc XXSon.m 编译后的.cpp文件之后的相关代码是:
static id _I_XXSon_init(XXSon * self, SEL _cmd) {
    self = ((XXSon *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("XXSon"))}, sel_registerName("init"));
    if (self)
    {
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_4c_2bxyjsn12ggc69ffj64bxvbc0000gn_T_XXSon_089961_mi_0, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class"))));
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_4c_2bxyjsn12ggc69ffj64bxvbc0000gn_T_XXSon_089961_mi_1, NSStringFromClass(((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("XXSon"))}, sel_registerName("class"))));
    }

return self;
}
结果分析
  1. 调用[self class]会转换成objc_msgSend(self, @selector(class))receiverself。调用class方法,因XXSon并未定义class方法,所以会从其父类XXFather中查找,XXFather中也未定义,会再从其父类 NSObject中查找。NSObject中的class方法会调用object_getClass()object_getClass()的定义在objc-class.mm文件中,具体如下:
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

[self class]receiverself,所以object_getClass这里的参数obj就是self。直接返回selfisaXXSon

  1. 调用[super class],会转化成objc_msgSendSuper, 同时会自动生成 struct objc_super *superobjc_super->receiverself(从.cpp文件中就可以看出来), objc_super-> super_classXXFather。所以直接从XXFather中查找class方法,在NSObject中找到class方法。最后调用objc_msgSend(objc_super->receiver, @selector(class)), 此时object_getClass()方法的receiverobjc_super->receiver(即self)。 所以和[self class]的打印一样。

你可能感兴趣的:(iOS分析[self class]和[super class])