美文网首页
superclass的位置以及它的作用

superclass的位置以及它的作用

作者: dandelionYD | 来源:发表于2018-12-28 20:27 被阅读0次

    本文所运行的环境是自己编译好的:配置运行objc4-750和使用
    本文所写的项目详见:OCBasicDemo

    从上一篇的<isa的位置以及它的作用>
    我们知道了superclass的位置
    下面我们来具体的在分析下这个superclass

    • class对象的superclass指针、meta-class对象的superclass指针
    我们先定义一个Person继承NNSobject对象,定义一个Student继承Person对象
    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    
    @interface Person:NSObject
    -(void)run;
    @end
    
    @implementation Person
    -(void)run{
        NSLog(@"run...");
    }
    @end
    
    @interface Student:Person
    
    @end
    @implementation Student
    
    @end
    
    struct my_class{
        Class isa;
        Class superclass;
    };
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            //instance 对象
            Student *stu  = [[Student alloc]init];
            Person *p = [[Person alloc]init];
            
            //class对象
            Class StuClass = object_getClass(stu);
            Class PerClass = object_getClass(p);
            
            //meta-class对象
            Class StuMetaClass = object_getClass(StuClass);
            Class PerMetaClass = object_getClass(PerClass);
            
            
            //转为结构体(类)
            struct my_class *stuC = (__bridge struct my_class *)(StuClass);
            //转为结构体(类)
            struct  my_class *perC = (__bridge struct my_class *)(PerClass);
            
            
            //转为结构体(元类)
            struct my_class *stuMetaC = (__bridge struct my_class *)(StuMetaClass);
            //转为结构体(元类)
            struct  my_class *perMetaC = (__bridge struct my_class *)(PerMetaClass);
            
            NSLog(@"End");
        }
        return 0;
    }
    

    说明:struct my_class{...},里面的is和superclass属性,是通过查看源代码的(自己可以command+鼠标左键)
    //打断点与NSLog(@"End");
    发现:

    输入: p/x stuC->superclass
    结果:(Class) $0 = 0x0000000100001220 Person
    输入: p/x perC
    结果:my_class *) $1 = 0x0000000100001220
    输入: p/x PerClass
    结果:(Class) $2 =  0x0000000100001220 Person
    
    输入: p/x stuMetaC->superclass
    结果:(Class) $3 = 0x00000001000011f8
    输入: p/x perMetaC
    结果:(my_class *) $4 = 0x00000001000011f8
    输入: p/x PerMetaClass
    结果:(Class) $5 = 0x00000001000011f8
    

    猜测:

    • 子类的类对象的superclass指向的是它的父类的类对象
    • 子类的元类对象的superclass指向的是它的父类的元类对象

    接下来我们加一些方法:如下(其中:my_objc_class定义,详情请见上一篇(isa指针))

    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    #import "myClassInfo.h"
    
    @interface Person:NSObject
    -(void)run;
    +(void)walk;
    @end
    
    @implementation Person
    -(void)run{
        NSLog(@"run...");
    }
    +(void)walk{
        NSLog(@"walk...");
    }
    @end
    
    @interface Student:Person
    
    @end
    
    @implementation Student
    
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            //instance 对象
            Student *stu  = [[Student alloc]init];
            Person *p = [[Person alloc]init];
            [p run];
            [Student walk];
            
            //class对象
            Class StuClass = object_getClass(stu);
            Class PerClass = object_getClass(p);
            
            //meta-class对象
            Class StuMetaClass = object_getClass(StuClass);
            Class PerMetaClass = object_getClass(PerClass);
            
            
            //转为结构体(类)
            struct my_objc_class *stuC = (__bridge struct my_objc_class *)(StuClass);
            class_rw_t  *stuCData = stuC->data();
            
            //转为结构体(类)
            struct  my_objc_class *perC = (__bridge struct my_objc_class *)(PerClass);
            class_rw_t  *perCData = perC->data();
            
            
            //转为结构体(元类)
            struct my_objc_class *stuMetaC = (__bridge struct my_objc_class *)(StuMetaClass);
            class_rw_t  *stuMetaCData = stuMetaC->data();
            
            //转为结构体(元类)
            struct  my_objc_class *perMetaC = (__bridge struct my_objc_class *)(PerMetaClass);
            class_rw_t  *perMetaCData = perMetaC->data();
            
            NSLog(@"End");
        }
        return 0;
    }
    

    分析:同样我们在** NSLog(@"End");**处打个断点
    发现:
    1.将鼠标放在stuCData:发现里面的方法列表为NULL,鼠标放在perCData:发现里面的方法列表有一个run(对象方法)
    2.将鼠标放在stuMetaCData:发现里面的方法列表为NULL,鼠标放在perMetaCData:发现里面的方法列表有一个walk(类方法)

    综上:

    • 1.当Studnent的instance对象要调用父类Person的对象方法,会先isa找到自己的类对象,然后通过里面的superclass指针 ,找到Person类对象,然后在找到Person对象里面的对象方法(run)去执行。
    • 2.当Student的class对象要调用父类Person的类方法,会先isa找到自己的元类对象,然后通过里面的superclass指针 ,找到Person元类对象,然后在找到Person元类对象里面的类方法(walk)去执行。

    具体的关系可见下图:


    image
    image

    友情链接:

    相关文章

      网友评论

          本文标题:superclass的位置以及它的作用

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