ios开发之runtime(一)

2020-06-01  本文已影响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学习参考

上一篇下一篇

猜你喜欢

热点阅读