一、Runtime

1、概念:

概念:Runtime是Objective-c言语动态的中心,即运转时。在面向目标的基础上增加了动态运转,到达许多在编译时确认办法推迟到了运转时,然后到达动态修正、确认、交流。。。特点及办法

效果: 这给程序员写代码带来很大的灵活性,比如说你可以把音讯转发给你想要的目标,或许随意交流一个办法的完成之类的!多态 kvo kvc 取得特点办法 增加特点办法

中心: 另外Runtime进行音讯解析和转发,动态调用过程!

只有在真实运转的时候才会依据函数的称号找 到对应的函数来调用。

2、特性:编写的代码具有有运转时、动态特性,然后衍生出 以下4、5


3、原理:Runtimer在Object-c的运用 程序在三个不同的层次上与运转时系统交互:

(1)经过Object-c源代码进行交互

(2)经过NSObject类中界说的办法交互

(3)经过直接调用运转时函数

4、效果:

(1)在程序运转过程中,动态的创立类,动态增加、修正这个类的特点的办法

(2)遍历一个类中的一切成员变量、特点、以及一切办法

(3)音讯传递、转发


5、典型事例:

(1)给系统分类增加特点、办法

(2)办法交流

(3)获取目标的特点、私有特点

(4)字典转化模型

(5)KVO、KVC

(6)(NSClassFromString class)字符串

(7)block

(8)类的自我检测

6、Objc-msgSend所做的事情

(1)找到办法的完成,由于经过单独的类以不同方式创立相同的办法,因此这个办法的完成的确认取决于接收音讯的类的目标,也既是说多个实例类对戏那个可以创立同样的办法,每个实例目标中该办法都是独立存在的

(2)调用该办法完成,将接收音讯类指针,以及该办法的参数传递给这个类

(3)最后将过程的回来值作为自己的回来值传递

7、音讯传递的要害要素

(1)指向superclass指针

(2)会有一个SEL跟办法完成的

8、Msg_sender机制:先查询本类是否又该办法的完成—>假如没有逐级找父类,还有一个快速映射表(提高性能)—> 匹配办法 —> 设置一个执行者—> 音讯转发 —> 没有完成办法

re solveInstanceMethod决策实力,动态办法解析
forwardingTargetForSelector转寄Target,设置一个执行者备用接收者

MethodSignatureForSelector办法签名,
forwardInvocation转寄求助,音讯重定向

doesNotRecognizeSelector 没有找到办法 溃散

iOS内功心法之“Runtime”原理篇

  • 先调用resolveInstanceMethod,假如在这里运用runtime动态增加对应的办法,并且回来YES,音讯就找到了呼应的目标,并将这个新增的办法增加到类的办法缓存列表
  • 假如上面的办法回来NO的话,目标会调用forwardingTargetForSelector办法,以完成音讯的转发,让其他目标来处理这个音讯。
  • 假如以上两个办法都没有做处理,那么目标会执行最后一个办法methodSignatureForSelector,供给一个有用的办法签名。若供给了有用的办法签名,程序会经过forwardInvocation办法执行签名。若没有供给办法签名,触发doesNotRecognizeSelector办法,触发溃散。

resolveInstanceMethod

resolveInstanceMethod是Objective-C言语中一种动态办法解析的接口,是得咱们可以在运转时动态的为一个selector供给完成。咱们只需求完成 +resolveInstanceMethod和+resolveClassMethod办法,并在其间为指定的selector供给完成即可(经过调用运转时函数class_addMethod来增加)。这两个办法都是NSObject中的类办法,其原型为:

+ (BOOL)resolveClassMethod:(SEL)name;
+ (BOOL)resolveInstanceMethod:(SEL)name;

参数那么是需求被动态解析的selector;假如在该函数中为指定的selector供给完成,不管回来YES仍是NO,编译运转都是正确的。假如在该函数内并没有真实的为selector供给完成,假如回来YES,运转会crash。其原理很简单,由于当时类既没有为selector供给完成,又没有完成音讯转发,自然会crash。

forwardingTargetForSelector

forwardingTargetForSelector是Objective-C言语中音讯快速重定向的函数。开发者可以在派生类中对其进行重载,然后将无法处理的selector转发给另一个目标。

methodSignatureForSelector

methodSigntureForSelector的效果在在于为另一个类完成的音讯创立一个有用的办法签名。假如没有完成有用的办法签名,程序就会溃散

forwardInvocation

在回来有用的办法签名的情况下,当时目标则会调用forwardInvocation办法,以完成音讯的最终传递。

1、动态解析的一个例子

iOS内功心法之“Runtime”原理篇

2、备用接受者

iOS内功心法之“Runtime”原理篇

3.重签名

iOS内功心法之“Runtime”原理篇

二、运转时常用的API:

objc_*

objc_系列函数重视于微观运用,如类与协议的空间分配,注册,刊出等操作

// 1.objc_xxx 系列函数
// 函数称号     函数效果
objc_getClass     获取Class目标
objc_getMetaClass     获取MetaClass目标
objc_allocateClassPair     分配空间,创立类(仅在 创立之后,注册之前 可以增加成员变量)
objc_registerClassPair     注册一个类(注册后方可运用该类创立目标)
objc_disposeClassPair     刊出某个类
objc_allocateProtocol     拓荒空间创立协议
objc_registerProtocol     注册一个协议
objc_constructInstance     结构一个实例目标(ARC下无效)
objc_destructInstance     析构一个实例目标(ARC下无效)
objc_setAssociatedObject     为实例目标相关目标
objc_getAssociatedObje*ct     获取实例目标的相关目标
objc_removeAssociatedObjects     清空实例目标的一切相关目标

class_*

class_系列函数重视于类的内部,如实例变量,特点,办法,协议等相关问题

// 2.class_xxx 系列函数
函数称号     函数效果
class_addIvar     为类增加实例变量
class_addProperty     为类增加特点
class_addMethod     为类增加办法
class_addProtocol     为类遵从协议
class_replaceMethod     替换类某办法的完成
class_getName     获取类名
class_isMetaClass     判别是否为元类
objc_getProtocol     获取某个协议
objc_copyProtocolList     复制在运转时中注册过的协议列表
class_getSuperclass     获取某类的父类
class_setSuperclass     设置某类的父类
class_getProperty     获取某类的特点
class_getInstanceVariable     获取实例变量
class_getClassVariable     获取类变量
class_getInstanceMethod     获取实例办法
class_getClassMethod     获取类办法
class_getMethodImplementation     获取办法的完成
class_getInstanceSize     获取类的实例的巨细
class_respondsToSelector     判别类是否完成某办法
class_conformsToProtocol     判别类是否遵从某协议
class_createInstance     创立类的实例
class_copyIvarList     复制类的实例变量列表
class_copyMethodList     复制类的办法列表
class_copyProtocolList     复制类遵从的协议列表
class_copyPropertyList     复制类的特点列表

objcet_*

objcet_系列函数重视于目标的角度,如实例变量


// 3.object_xxx 系列函数
函数称号     函数效果
object_copy     目标copy(ARC无效)
object_dispose     目标释放(ARC无效)
object_getClassName     获取目标的类名
object_getClass     获取目标的Class
object_setClass     设置目标的Class
object_getIvar     获取目标中实例变量的值
object_setIvar     设置目标中实例变量的值
object_getInstanceVariable     获取目标中实例变量的值 (ARC中无效,运用object_getIvar)
object_setInstanceVariable     设置目标中实例变量的值 (ARC中无效,运用object_setIvar)

method_*

method_系列函数重视于办法内部,假如办法的参数及回来值类型和办法的完成

// 4.method_xxx 系列函数
函数称号     函数效果
method_getName     获取办法名
method_getImplementation     获取办法的完成
method_getTypeEncoding     获取办法的类型编码
method_getNumberOfArguments     获取办法的参数个数
method_copyReturnType     复制办法的回来类型
method_getReturnType     获取办法的回来类型
method_copyArgumentType     复制办法的参数类型
method_getArgumentType     获取办法的参数类型
method_getDescription     获取办法的描述
method_setImplementation     设置办法的完成
method_exchangeImplementations     替换办法的完成

property_*

property_系类函数重视与特点*内部,如特点的特性等


// 5.property_xxx 系列函数
函数称号     函数效果
property_getName     获取特点名
property_getAttributes     获取特点的特性列表
property_copyAttributeList     复制特点的特性列表
property_copyAttributeValue     复制特点中某特性的值

protocol_*


// 6.protocol_xxx 系列函数
函数称号     函数效果
protocol_conformsToProtocol     判别一个协议是否遵从另一个协议
protocol_isEqual     判别两个协议是否共同
protocol_getName     获取协议称号
protocol_copyPropertyList     复制协议的特点列表
protocol_copyProtocolList     复制某协议所遵从的协议列表
protocol_copyMethodDescriptionList     复制协议的办法列表
protocol_addProtocol     为一个协议遵从另一协议
protocol_addProperty     为协议增加特点
protocol_getProperty     获取协议中的某个特点
protocol_addMethodDescription     为协议增加办法描述
protocol_getMethodDescription     获取协议中某办法的描述

ivar_*

// 7.ivar_xxx 系列函数
函数称号     函数效果
ivar_getName     获取Ivar称号
ivar_getTypeEncoding     获取类型编码
ivar_getOffset     获取偏移量

sel_*

// 8.sel_xxx 系列函数
函数称号     函数效果
sel_getName     获取称号
sel_getUid     注册办法
sel_registerName     注册办法
sel_isEqual     判别办法是否持平

imp_*

// 9.imp_xxx 系列函数
函数称号     函数效果
imp_implementationWithBlock     经过代码块创立IMP
imp_getBlock     获取函数指针中的代码块
imp_removeBlock     移除IMP中的代码块