Objective-C Runtime学习笔记
来源:互联网 发布:sql where语句 1,4 编辑:程序博客网 时间:2024/05/01 19:53
1.objc_msgSend函数
在Objective-C(以下简称OC)中,消息只有在运行期间才会绑定到具体的方法实现。编译器会将一个发送消息转为一个C函数,例如[receiver message]
会转为objc_msgSend。此函数将receiver和message作为两个主要的参数。也即objc_msgSend(receiver, message)
。此函数则可以在运行期进行动态绑定。主要过程包括一下三个:
①首先找到message指向的方法实现。由于同一个方法名称可能在不同的类中有实现,objc_msgSend通过receiver找到正确的方法;
②然后调用方法,将方法及其参数发送给receiver;
③最后,将方法的返回值作为自己的返回值。
根据苹果官方文档注明的,我们不能直接调用此方法。
消息转发是建立在编译器为每个类和对象所建立的结构基础上的,每个类包括了两个基本的元素(elements):
①一个指向父类的指针。
②一个类转发表(dispatch table)。这个表是消息选择器(selector)及与之相关联的消息地址的入口。
下图是类和对象架构的原理图
当一个新的对象被创建,并分配内存,它的实例变量被初始化。第一个实例变量是一个名叫isa的指针,它指向自己的类结构(class structure)。它使对象能够操作(access)自己的类以及父类。
当一个消息被发送时,消息发送函数通过isa指针去找到类,并在这个类的转发表中去寻找这个方法,如果在此类中没有找到此方法,objc_msgSend则会顺着指针往父类的转发表中查询,如果父类依然找不到,则会顺着继承树往上继续查找,一直查找到NSOjbect类。
2.获取消息地址
如果不想在运行期进行动态绑定,则可以获取消息地址进行直接调用。可以通过方法methodForSelector:来获取指向消息的指针。以下是代码示例:
//声明一个指向函数的指针settervoid (*setter)(id, SEL, BOOL);int i;//通过方法methodForSelector获取selector的函数地址setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(method)];//循环调用method 100次for (i = 0; i < 100; i++) { setter(targetList[i], @selector(method), YES);}
3.给类动态添加方法
我们还可以给类动态添加方法,代码如下
+ (BOOL)addMethods:(SEL)aSEL { class_addMethod([self class], aSEL, (IMP)dynamicMethodIMP, @"v@:");}
class_addMethod第一个参数指定方法添加到哪个类, aSEL为方法名称,
IMP是implementation的简称,指向具体实现的地址,他必须接受两个参数:self 和 _cmd。例如:
void dynamicMethodIMP(id self, SEL _cmd) {}
- Objective-C Runtime学习笔记
- Objective-C Runtime学习笔记
- iOS学习笔记56(Runtime)- Objective-C Runtime 运行时之一:类与对象
- iOS学习笔记56(Runtime)-Objective-C Runtime 运行时之三:方法与消息
- iOS学习笔记56(Runtime)-Objective-C Runtime 运行时之四:Method Swizzling
- iOS学习笔记56(Runtime)-Objective-C Runtime 运行时之五:协议与分类
- iOS学习笔记56(Runtime)-Objective-C Runtime 运行时之六:拾遗
- Objective C Runtime的一些笔记
- Objective-C Runtime Programming Guide 笔记01
- Objective-C 的Runtime的学习
- ios学习--Objective-C runtime的使用
- 初步学习objective-c的Runtime机制
- Objective-C学习笔记
- Objective-C 学习笔记
- Objective-C学习笔记
- objective c 学习笔记
- Objective-C 学习笔记
- Objective-C学习 笔记
- AFTN和SITA报文简介
- drbd 学习笔记
- 解决eclipse新建servers时选中tomcat版本后不能继续操作
- 在 Linux 上使用 Jexus + Mono 建立 Asp.Net 网站.
- IT软件创业之 -- 曾经热血沸腾软件创业、技术带人犯下的幼稚错误总结
- Objective-C Runtime学习笔记
- C++中const重载
- FreeSwitch SIP(1):linux下编译安装v1.4
- ubuntu设置cairo-dock自启动
- 以客户为中心,群策CRM为IT企业谋产销方案
- 公司
- Linux系统下安装rz/sz命令及使用说明
- java NIO
- MyEclipse移动Web模拟器指南(二)