runtime基础

2017-04-18  本文已影响20人  UILabelkell

目前我所了解的Runtime内容大约有:动态获取类名、动态获取类的成员变量、动态获取类的属性列表、动态获取类的方法列表、动态获取类所遵循的协议列表、动态添加新的方法、类的实例方法实现的交换、动态属性关联、消息发送与消息转发机制
1、实现方法交换
<pre>
-(void)initWithVie
{
UIButton *btu = [UIButton buttonWithType:UIButtonTypeCustom];
btu.frame = CGRectMake(100, 100, 80, 40);
btu.backgroundColor = [UIColor orangeColor];
[btu addTarget:self action:@selector(clickent:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btu];
}

-(void)clickent:(UIButton *)btn
{
Method m1 = class_getInstanceMethod([self class], @selector(stringStr));
Method m2 = class_getInstanceMethod([self class], @selector(withview));
method_exchangeImplementations(m1, m2);

[self stringStr];
[self withview];

}

-(void)stringStr
{
NSLog(@"%s ---1",FUNCTION);
}

-(void)withview
{
NSLog(@"%s---2",FUNCTION);
}
</pre>
原理:OC的方法调用会在底层转换为向该对象发送消息。这由C语言的函数完成。是通过查找接收消息对象的方法列表,从方法列表中查找对应的SEL,这个SEL对应着一个IMP(一个IMP可以对应多个SEL),通过这个IMP找到对应的方法调用。

在每个类中都有一个Dispatch Table,这个Dispatch
Table本质是将类中的SEL和IMP(可以理解为函数指针)进行对应。而我们的Method
Swizzling就是对这个table进行了操作,让SEL对应另一个IMP。
如图
交换前:


003YMHs7gy72CEFH1e525&690.jpeg

交换后

003YMHs7gy72CEKEp7r51&690.jpeg

2.获取类名 方法
<pre>
/**
获取类名

@param class 相应类
@return NSString:类名
*/

3.获取成员变量
<pre>/**
获取成员变量

@param class Class
@return NSArray
*/

</pre>

3.获取类的属性列表, 包括私有和公有属性,以及定义在延展中的属性
<pre>/**
获取类的属性列表, 包括私有和公有属性,以及定义在延展中的属性

@param class Class
@return 属性列表数组
*/

4.获取类的实例方法列表:getter, setter, 对象方法等。但不能获取类方法
<pre>/**
获取类的实例方法列表:getter, setter, 对象方法等。但不能获取类方法

@param class <#class description#>
@return <#return value description#>
*/

  1. 获取协议列表
    <pre>/**
    获取协议列表

@param class <#class description#>
@return <#return value description#>
*/

  1. 往类上添加新的方法与其实现
    <pre>
    /**
    往类上添加新的方法与其实现

@param class 相应的类
@param methodSel 方法的名
@param methodSelImpl 对应方法实现的方法名
*/

//运行时方法拦截

/**
没有找到SEL的IML实现时会执行下方的方法

@param sel 当前对象调用并且找不到IML的SEL
@return 找到其他的执行方法,并返回yes
*/

/**
将当前对象不存在的SEL传给其他存在该SEL的对象

@param aSelector 当前类中不存在的SEL
@return 存在该SEL的对象
*/

上一篇下一篇

猜你喜欢

热点阅读