Runtime机制的使用整理
一.基本概念
1.1、RunTime简称运行时,就是系统在运行的时候的一些机制,其中最主要的是消息机制。
1.2、对于C语言,函数的调用在编译的时候会决定调用哪个函数,编译完成之后直接顺序执行,无任何二义性。
1.3、OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。
1.4、只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用
二.知晓OC的方法调用在Runtime中具体的实现
1.OC代码调用一个方法
[self.loginBt login];
2.在编译时RunTime会将上述代码转化成[发送消息]
objc_msgSend(self.loginB,@selector(login));
三.常见的作用
1. 动态的添加对象的成员变量和方法
2. 动态交换两个方法的实现
3. 实现分类也可以添加属性
4. 实现NSCoding的自动归档和解档
5. 实现字典转模型的自动转换
四.编写代码实现
1. 动态变量控制
Teacher: What's your name?
XiaoMing: My name isXiaoMing.
Teacher: Pardon?
XiaoMing: My name is__
在程序当中,假设XiaoMing的name原来的值为XiaoMing,后来被Runtime偷换了一个名字叫Minggo。那么,Runtime是如何做到的呢?
①动态获取XiaoMing类中的所有属性[当然包括私有]
Ivar *ivar = class_copyIvarList([self.xiaoMing class], &count);
②遍历属性找到对应name字段
constchar *varName = ivar_getName(var);
③修改对应的字段值成Minggo
object_setIvar(self.xiaoMing, var, @"Minggo");
3)Show Code:
-(void)answer{
unsignedint count = 0;
Ivar *ivar = class_copyIvarList([self.xiaoMing class], &count);
for (int i = 0; i<count; i++) {
Ivar var = ivar[i];
constchar *varName = ivar_getName(var);
NSString *name = [NSString stringWithUTF8String:varName];
if ([name isEqualToString:@"_englishName"]) {
object_setIvar(self.xiaoMing, var, @"Minggo");
break;
}
}
NSLog(@"XiaoMing first answer is %@",self.xiaoMing.englishName);
self.nameTf.text = self.xiaoMing.englishName;
}
2. 动态交换方法
1)Sense:
Teacher: What's your name?
XiaoMing: My name isXiaoMing.
Teacher: Pardon?
XiaoMing: My name is__
在程序当中,假设XiaoMing的第一次回答为firstSay,后来被Runtime交换了一个名字叫secondSay的方法,最终再调用firstSay的时候,其实是调用了secondSay的实现。那么,Runtime是如何做到的呢?
2)Step:
①动态找到firstSay和secondSay方法
Method m1 = class_getInstanceMethod([self.xiaoMing class], @selector(firstSay));
Method m2 = class_getInstanceMethod([self.xiaoMing class], @selector(secondSay));
②交换两个方法
method_exchangeImplementations(m1, m2);
3)Show Code:
-(void)answer{
Method m1 = class_getInstanceMethod([self.xiaoMing class], @selector(firstSay));
Method m2 = class_getInstanceMethod([self.xiaoMing class], @selector(secondSay));
method_exchangeImplementations(m1, m2);
NSString *secondName = [self.xiaoMing firstSay];
self.nameTf.text = secondName;
NSLog(@"XiaoMing:My name is %@",secondName);
}
3. 动态添加方法
1)Sense:
Teacher: WhereisLiLei from?
XiaoMing: I don't know.
Teacher: Guess?.
LiHua: Heis from __
在程序当中,假设XiaoMing的中没有guess这个方法,后来被Runtime添加一个名字叫guess的方法,最终再调用guess方法做出相应。那么,Runtime是如何做到的呢?
2)Step:
①动态给XiaoMing类中添加guess方法:
class_addMethod([self.xiaoMing class], @selector(guess), (IMP)guessAnswer, "v@:");
这里参数地方说明一下:
(IMP)guessAnswer 意思是guessAnswer的地址指针;
"v@:" 意思是,v代表无返回值void,如果是i则代表int;@代表 id sel; : 代表 SEL _cmd;
“v@:@@” 意思是,两个参数的没有返回值。
②调用guess方法响应事件:
[self.xiaoMing performSelector:@selector(guess)];
③编写guessAnswer的实现:
void guessAnswer(idself,SEL _cmd){
NSLog(@"He is from GuangTong");
}
这个有两个地方留意一下:
1.void的前面没有+、-号,因为只是C的代码。
2.必须有两个指定参数(id self,SEL _cmd)
3)Show Code:
-(void)answer{
class_addMethod([self.xiaoMing class], @selector(guess), (IMP)guessAnswer, "v@:");
if ([self.xiaoMing respondsToSelector:@selector(guess)]) {
[self.xiaoMing performSelector:@selector(guess)];
} else{
NSLog(@"Sorry,I don't know");
}
self.cityTf.text = @"GuangTong";
}
void guessAnswer(idself,SEL _cmd){
NSLog(@"He is from GuangTong");
}
4. 动态为Category扩展加属性
这一点上有两点要表达一下:第一,XCode运行你在Category的.h文件申明@Property,编译通过,但运行时如果没有Runtime处理,进行赋值取值,就马上报错。第二,这一点是iOS面试当中经常面到的问题:如何给扩展添加属性?。
1)Sense:
Teacher: What's your Chinese name?
XiaoMing: I have no one.
LiHua: You should have one.
LiHua: YourChinese name is __
在程序当中,假设XiaoMing的中没有chineseName这个属性,后来被Runtime添加一个名字叫chineseName的属性。那么,Runtime是如何做到的呢?
2)Step:
①申明chineseName属性
#import "XiaoMing.h"@interfaceXiaoMing (MutipleName)@property(nonatomic,copy) NSString *chineseName;
@end
②动态添加属性和实现方法
#import "XiaoMing+MutipleName.h"#import <objc/runtime.h>@implementationXiaoMing (MutipleName)char cName;
-(void)setChineseName:(NSString *) chineseName{
objc_setAssociatedObject(self, &cName, chineseName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)chineseName{
return objc_getAssociatedObject(self, &cName);
}
@end
③使用chineseName属性
-(void)answer{
NSLog(@"My Chinese name is %@",self.xiaoMing.chineseName);
self.chineseNameTf.text = self.xiaoMing.chineseName;
}
原文地址:http://www.jianshu.com/p/8916ad5662a2 谈Runtime机制和使用的整体梳理
Runtime机制的使用整理的更多相关文章
- Objective-C的对象模型和runtime机制
内容列表 对象模型(结构定义,类对象.元类和实例对象的关系) 消息传递和转发机制 runtime系统功能理解 对象模型 结构定义 对象(Object): OC中基本构造单元 (building blo ...
- iOS开发之深入探讨runtime机制02-runtime的简单使用
runtime机制为我们提供了一系列的方法让我们可以在程序运行时动态修改类.对象中的所有属性.方法. 下面就介绍运行时一种很常见的使用方式,字典转模型.当然,你可能会说,“我用KVO直接 setVal ...
- iOS开发之深入探讨runtime机制01-类与对象
最近有个同事问我关于“runtime机制”的问题,我想可能很多人对这个都不是太清楚,在这里,和大家分享一下我对于runtime机制的理解.要深入理解runtime,首先要从最基本的类与对象开始,本文将 ...
- iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行
一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头 ...
- Runtime机制之结构体及操作函数
一.动态语言 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:具有灵活性,比如:消息转发,方法交换等.它有一个运行时系统Ob ...
- Objective-C runtime 机制
Runtime使用C语言结构体表示对象,用C语言函数表示方法,这些C语言函数和结构体被Runtime封装后,我们就可以在程序中执行创建,检查,修改类和对象和他们的方法 OC的Class其实是一个obj ...
- runtime机制
runtime(简称运行时),是一套 纯C(C和汇编写的) 的API.而 OC 就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 消息机制原理:对象根据方法编号SEL去映射表查找对 ...
- iOS开发之Runtime机制深入解析
本篇主要讲述在 OC 开发中主要涉及到的运行时机制: 运行时的工作: 运行时在 OC 中的工作:OC 语言的设计模式决定了尽可能的把程序从编译和链接时推迟到运行时.只要有可能,OC 总是使用动态的方式 ...
- objective-c底层: runtime机制
runtime是oc的真面目.oc底层的一套c语言API. unsigned int count; //获取属性列表 objc_property_t *propertyList = class_cop ...
随机推荐
- 更改jmeter发送邮件样式(转)
http://www.cnblogs.com/puresoul/p/5049433.html Jmeter默认的报告展示的信息比较少,如果出错了,不是很方便定位问题.由Jmeter默认报告优化这篇文章 ...
- Java中的算术运算符
算术运算符主要用于进行基本的算术运算,如加法.减法.乘法.除法等. Java 中常用的算术运算符: 其中,++ 和 -- 既可以出现在操作数的左边,也可以出现在右边,但结果是不同滴 例1: 运行结果: ...
- 二十种实战调优MySQL性能优化的经验
http://www.searchdatabase.com.cn/showcontent_58391.htm [为查询缓存优化你的查询] 像 NOW() 和 RAND() 或是其它的诸如此类的S ...
- Remoting 学习一调用远程的类就像调用本地的类一样
Remoting 使用TCP/IP 协议,服务端可以是服务,web服务器,类. 例子1. 远程调用服务端的类,就像调用客户端机器上的类一样. 服务端代码 (先定义被客户端调用的类,然后注 ...
- HTTP通道
通过httptunnel技术进行入侵示例 httptunnel是通过HTTP通道来传输其他协议数据的工具软件,下载地址为:www.http-tunnel. com,目前最新版本3.0.5 工具/原料 ...
- StratifiedShuffleSplit 交叉验证
python中数据集划分函数StratifiedShuffleSplit的使用 文章开始先讲下交叉验证,这个概念同样适用于这个划分函数 1.交叉验证(Cross-validation) 交叉验证是指在 ...
- ImageSwitcher的简单使用
测试代码: activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <Linear ...
- mysql索引攻略
本设计和优化专题转自博客园的Mysql的设计和优化专题 Explain优化查询检测 所谓索引就是为特定的mysql字段进行一些特定的算法排序,比如二叉树的算法和哈希算法,哈希算法是通过建立特征值,然后 ...
- memcache应对缓存失效问题
.两个key,一个key用来存放数据,另一个用来标记失效时间 比如key是aaa,设置失效时间为30s,则另一个key为expire_aaa,失效时间为25s. 在取数据时,用multiget,同时取 ...
- Agc019_C Fountain Walk
传送门 题目大意 给定网格图上起点和终点每个格子是长为$100$米的正方形,你可以沿着线走. 平面上还有若干个关键点,以每个关键点为圆心,$10$为半径画圆,表示不能进入圆内的线,但是可以从圆周上走, ...