美文网首页
Runtime(1) 类到结构体

Runtime(1) 类到结构体

作者: iOS资深入门 | 来源:发表于2020-06-07 20:11 被阅读0次

    Runtime是一套C语言的API,封装了很多动态性相关的函数,平时编写的OC代码,底层都是转换成了Runtime API进行调用。
    Runtime主要是用于在程序运行过程中,对OC对象做一系列的操作。

    NSString类的实例,其实就是一个struct objc_object结构体的指针,所以不管是Foundation框架中的类或是自定义的类,我们创建的类的实例最终获取的都是一个结构体指针,这个结构体只有一个成员变量就是Class类型的isa指针,Class是结构体指针,指向struct objc_class。Class就是代表NSString这个类。

        NSString * str = @"123";
        Class c = [str class];
    

    通过实例对象的class方法,我们可以获取到一个Class类型的变量,我们可以通过这个Class来创建相应的实例对象。

    实际上,OC中的类也是一个对象,称为类对象,上述方法中通过[str class]方法获取到的就是NSString类的类对象,接着,我们就可以通过这个类对象来创建实例对象。那这个类对象,就是结构体sruct objc_class。

    struct objc_class结构体定义了很多变量,通过命名不难发现,结构体里保存了指向的指针、类名、版本、实例大小、实例变量列表、方法列表、缓存、遵守的协议列表。因此可见,类对象就是一个结构体 struct objc_class,这个结构体存放的数据称为元数据,该结构体的第一个成员变量也是isa指针,这就说明了Class本身其实也是一个对象,因此我们称之为类对象,类对象在编译期产生用于创建实例对象,是单例。

    类对象中的元数据存储的都是创建一个实例的相关信息,那么,类对象和类方法应该从哪里创建呢?就是从isa指针指向的结构体创建,类对象的isa指针指向的我们称之为元类(metaclass),元类中保存了创建类对象以及类方法所需要的所有信息。
    c是通过一个实例对象获取的Class,实例对象可以获取到其类对象,类名作为消息的接收者时,代表的是类对象,因此类对象获取Class得到的是其本身,同时也印证了类对象是一个单例的想法。

        NSLog(@"object_getClass = %@", object_getClass(p));
        NSLog(@"isMetaClass = %@", class_isMetaClass(object_getClass(p))? @"yes": @"no");
        NSLog(@"isMetaClass = %@", class_isMetaClass(object_getClass([Person class]))? @"yes":@"no");
        NSLog(@"\nclass1=%@\nclass2=%@", object_getClass(p), object_getClass([Person class]));
    

    一个实例对象通过class方法获取的Class就是它的isa指针指向的类对象,而类对象不是元类,类对象的isa指针指向的对象是元类。

    isa

    isa是一个联合体的结构
    对象的isa地址 & ISA_MASK 得到类地址
    类isa地址 & ISA_MASK 得到元类地址

    #   define ISA_MASK        0x00007ffffffffff8ULL
    

    实例对象是一个结构体,这个结构体只有一个成员变量,指向构造它的那个类对象,这个类对象中存储了一切实例对象需要的信息,包括实例变量,实例方法等而类对象是通过元类创建的,元类中保存了类变量和类方法,这就是类映射到结构体的过程。

    alloc

    alloc --> 
    id _objc_rootAlloc(Class cls) --> 
    static ALWAYS_INLINE id callAlloc(Class cls, bool checkNil, bool allocWithZone=false) --> 
    class_createInstance --> 
    id class_createInstance(Class cls, size_t extraBytes)
    

    init

    id _objc_rootInit(id obj)
    {
        // In practice, it will be hard to rely on this function.
        // Many classes do not properly chain -init calls.
        return obj;
    }
    

    交由子类去重写

    相关文章

      网友评论

          本文标题:Runtime(1) 类到结构体

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