美文网首页
iOS分析[self class]和[super class]

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

作者: 落夏简叶 | 来源:发表于2020-05-17 12:00 被阅读0次

    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]

          本文链接:https://www.haomeiwen.com/subject/dfjbnhtx.html