美文网首页
ios开发之runtime(一)

ios开发之runtime(一)

作者: 我是卖报的小行家 | 来源:发表于2020-06-01 16:52 被阅读0次

    1.概述
    oc为运行时语言,也就是说在编译阶段,我们并不知道变量的具体数据类型,也不知道真正所调用的哪个函数,只有在运行时间才检查变量的数据类型,同时在运行时才会根据函数名查找要调用发具体函数。
    oc把一些决定性的工作从编译阶段,链接阶段推迟到运行时阶段的机制,使得oc变得更加灵活,我们甚至可以再程序运行时候,动态的去修改一个方法的实现。而实现oc运行时机制的一切基础就是runtime
    \color{red}{runtime实际上就是一个库,这个库使得我们可以再程序运行时动态的创建对象,检查对象,修改类和对象的方法。}

    2.原理
    所有oc方法调用在编译的时都会转化为对c函数objc_msgSend的调用
    objc_msgSend(receiver,selector)是[receiver selector]对应的C函数

    oc对象中,对象方法调用是以[receiver selector]的形式,其本质就是让对象在运行时候发送消息
    在编译阶段:
    [receiver selector] 方法被编译器转换为:
    1.objc_msgSend(receiver,selector)(不带参数)
    2.objc_msgSend(receiver,selectorr,org1,org2,...)(不带参数)
    在运行时阶段 receiver寻找对应的selector
    1.通过receiver的isa指针找到receiver的class类
    2.在class类的cache的散列表中寻找对应的imp实现
    3.如果cache缓存中没有找到对应的imp实现,就继续在class类中的method list中找对应的selector,如果找到就填充到cache缓存中,并返回selector给receiver
    4.如果在class类的method list中还没有找到selector,就继续在superClass父类中寻找;
    5.一旦找到对应的selector,直接执行receiver对应的selector的imp实现方法
    6.若还是找不到对应的selector,消息被转发或者临时向receiver添加这个selector对应的imp方法,那么就会发生崩溃。

    关于一些关键词
    1.instancetype
    我们用id 类型声明一个对象其本质是一个结构体:
    /// An opaque type that represents an Objective-C class.
    typedef struct objc_class *Class;

    /// Represents an instance of a class.
    struct objc_object {
    Class isa OBJC_ISA_AVAILABILITY;
    };

    /// A pointer to an instance of a class.
    typedef struct objc_object *id;

    通过源代码分析:我们创建的一个对象或实例其实就是一个struct objc_object结构体,而我们常用的id也就是这个结构体的指针。这个结构体只有一个成员变量,这是一个class类型的变量isa,也是一个结构体指针,这个isa指针指向对象所属的类,根据这个类模板能创建出实例变量和实例方法
    eg: NSString * name = @"James";
    name本质为一个objc_object结构体,这个结构体成员变量isa指针则表示 那么为NSString类型,isa指向了NSString类,而NSString类其实是一个类对象。

    class object(类对象)/metaclass(元类)
    结构体 objc_class结构体里存放的数据为metaclass,里面包括:1.isa指针,指向父类的指针,类的名字,版本,实例大小,实例变量列表,方法列表,缓存,协议列表等。Class本身也是一个对象叫做类对象,作用是在编译期产生用于创建实例对象,是单例!
    类对象中的元数据存储的都是如何创建一个实例的相关信息,那么类对象类方法应该从哪里创建呢?就是从isa指针指向的结构体创建,类对象isa指针指向的我们称之为元类(metaclass)元类中保存了创建类对象以及类方法所需的所有信息,因此整个结构应该如下图所示:

    image

    一个实例对象也就是struct objc_object结构体它的isa指针指向类对象,类对象的isa指针指向了元类,super_class指针指向了父类的类对象,而元类的super_class指针指向了父类的元类

    1853063-ab35405f00cf1bfc.png

    整个体系构成了一个自闭环,如果是从NSObject中继承而来的上图中的Root class就是NSObject。

    class_isMetaClass用于判断Class对象是否为元类,object_getClass用于获取对象的isa指针指向的对象。

    声明:原文转载自https://www.jianshu.com/p/633e5d8386a8学习参考

    相关文章

      网友评论

          本文标题:ios开发之runtime(一)

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