一.基本概念

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. 动态变量控制

1)Sense:
Teacher: What's your name?
XiaoMing: My name isXiaoMing.
Teacher: Pardon?
XiaoMing: My name is__

在程序当中,假设XiaoMing的name原来的值为XiaoMing,后来被Runtime偷换了一个名字叫Minggo。那么,Runtime是如何做到的呢?

 
2)Step:

①动态获取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机制的使用整理的更多相关文章

  1. Objective-C的对象模型和runtime机制

    内容列表 对象模型(结构定义,类对象.元类和实例对象的关系) 消息传递和转发机制 runtime系统功能理解 对象模型 结构定义 对象(Object): OC中基本构造单元 (building blo ...

  2. iOS开发之深入探讨runtime机制02-runtime的简单使用

    runtime机制为我们提供了一系列的方法让我们可以在程序运行时动态修改类.对象中的所有属性.方法. 下面就介绍运行时一种很常见的使用方式,字典转模型.当然,你可能会说,“我用KVO直接 setVal ...

  3. iOS开发之深入探讨runtime机制01-类与对象

    最近有个同事问我关于“runtime机制”的问题,我想可能很多人对这个都不是太清楚,在这里,和大家分享一下我对于runtime机制的理解.要深入理解runtime,首先要从最基本的类与对象开始,本文将 ...

  4. iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行

    一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头 ...

  5. Runtime机制之结构体及操作函数

    一.动态语言 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:具有灵活性,比如:消息转发,方法交换等.它有一个运行时系统Ob ...

  6. Objective-C runtime 机制

    Runtime使用C语言结构体表示对象,用C语言函数表示方法,这些C语言函数和结构体被Runtime封装后,我们就可以在程序中执行创建,检查,修改类和对象和他们的方法 OC的Class其实是一个obj ...

  7. runtime机制

    runtime(简称运行时),是一套 纯C(C和汇编写的) 的API.而 OC 就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 消息机制原理:对象根据方法编号SEL去映射表查找对 ...

  8. iOS开发之Runtime机制深入解析

    本篇主要讲述在 OC 开发中主要涉及到的运行时机制: 运行时的工作: 运行时在 OC 中的工作:OC 语言的设计模式决定了尽可能的把程序从编译和链接时推迟到运行时.只要有可能,OC 总是使用动态的方式 ...

  9. objective-c底层: runtime机制

    runtime是oc的真面目.oc底层的一套c语言API. unsigned int count; //获取属性列表 objc_property_t *propertyList = class_cop ...

随机推荐

  1. Qt QT的IO流 QT输入输出

    1. QFile QDataStream 读写文件  二进制读写文件 #include <QApplication> #include <QtGui> #include < ...

  2. tp后台注册登录配置项

    1.在application目录下Common/Conf/config.php中 2-17行,首先判断在data目录下有没有特意设置的db.php, config.php,route.php,如果有就 ...

  3. andriod sdk 模拟器的安装以及root

    安卓模拟器常用的一共2种java sdk 和 bluestacks 蓝手指.前者比较卡,后者貌似不能模拟2g/3g上网.   本文主要是针对java sdk的安装使用,以及root.关于root的意思 ...

  4. JAVA实现多线程的四种方式

    JAVA多线程实现方式: 1.继承Thread类(无返回值) 2.实现Runnable接口(无返回值) 3.实现Callable接口,通过FutureTask包装器来创建Threak线程(有返回值) ...

  5. pandas 中文快速查询手册

    本文翻译自文章: Pandas Cheat Sheet - Python for Data Science ,同时添加了部分注解. 对于数据科学家,无论是数据分析还是数据挖掘来说,Pandas是一个非 ...

  6. KVM- vnc配置

    本文是通过vnc方式访问虚拟主机上的KVM虚拟机. 这里的通过vnc方式访问虚拟机不是在kvm虚拟机安装配置vnc服务器,通过虚拟主机的IP地址与端口进行访问,kvm虚拟化对vnc的支持相对来说比xe ...

  7. 延时并自动关闭MessageBox

    信息提示框(MessageBox)是微软NET自带的一个用于弹出警告.错误或者讯息一类的“模式”对话框.此类对话框一旦开启,则后台窗体无法再被激活(除非当前的MessageBox被点击或者关闭取消). ...

  8. Dev c++在新建文件中插入文件头

    在菜单栏中依次点击Tools->Editor Options->Snippets->Default Source 勾选Insert the following code into e ...

  9. Linux运维工程师中级面试题

    1.解释top命令和vmstat命令 2.请写出iptables语句 3.mysql高可用方案有哪些?mysql备份方案有哪些?有什么缺点? 4.写出Apache 2.x的两种工作模式,以及各自的工作 ...

  10. 修改altibase MDB中的复制表的表结构

    前提条件:有MDB两个数据库,且知道普通用户和sys用户的密码等基本信息.操作:1:用sys用户登录isqlisql -s 127.0.0.1 -u sys -p manager -port 2030 ...