super

作者: Berning | 来源:发表于2021-11-05 19:05 被阅读0次

    示例

    #import "NSPerson.h"
    
    @interface NSStudent : NSPerson
    
    - (void)superTest;
    
    @end
    
    
    #import "NSStudent.h"
    
    @implementation NSStudent
    
    - (void)superTest
    {
        NSLog(@"self_class:%@",[self class]);
        NSLog(@"self_superclass:%@",[self superclass]);
        NSLog(@"super_class:%@",[super class]);
        NSLog(@"super_superclass:%@",[super superclass]);
    }
    
    @end
    
    #import "NSStudent.h"
    
    int main(int argc, const char * argv[]) {
            
        NSStudent *student = [[NSStudent alloc] init];
        [student superTest];
        return 0;
    }
    
    
    //log
    2020-08-27 23:59:48.669409+0800 runtime[14450:547436] self_class:NSStudent
    2020-08-27 23:59:48.669912+0800 runtime[14450:547436] self_superclass:NSPerson
    2020-08-27 23:59:48.670006+0800 runtime[14450:547436] super_class:NSStudent
    2020-08-27 23:59:48.670052+0800 runtime[14450:547436] super_superclass:NSPerson
    Program ended with exit code: 0
    
    

    self

    [self class]、[self superclass]调用流程

        ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class"));
        ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("superclass"));
    

    super

    [super class]、[super superclass]调用流程

    struct objc_super {
        id receiver;
        Class super_class;
    };
    
    id  objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
    
    
        ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("NSStudent"))}, sel_registerName("class"));
        ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("NSStudent"))}, sel_registerName("superclass"));
    
    

    说明:super调用方法,本质是调用objc_msgSendSuper给对象发送消息

    objc_msgSendSuper第一个参数struct objc_super * _Nonnull super是一个结构体,封装了消息接收者(receiver)和父类对象(super_class)

    第二个参数是方法本身

    通过源码可以看出,消息接收者receiver仍然是当前对象self ,suerper_class是当前对象类对象的父类,作用是查找方法时从父类开始查找

    注意:转换成的c++代码与程序实际运行转换成的代码有出入.
    实际运行过程中,是调用objc_msgSendSuper2, 第一个参数struct objc_super * _Nonnull super结构体内部的第二个成员变量就是当前类

    相关文章

      网友评论

          本文标题:super

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