目录
- 1 反射机制的概念
- 2 反射机制原理
首先还是按照惯例和大家解释下什么反射机制?
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。
当然反射机制的提出在java中的概念是这样的-
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
所以当然反射机制在oc中的使用状态也是一样的,那么它在OC语言当中能够实现哪些功能呢?
动态的运行状态下我们可以构造任意一个类,然后我们通过这个类知道这个类的所有属性和方法,并且如果我们创建一个对象,我们也可以通过对象找到这个类的任意一个方法,这就是反射机制
为了显示反射机制的内容,我们可以直接用一个实例对象或类对象,直接调用Class方法,都可以获取Class对象。我们调用下面三个方法,都可以获得Class对象。
- 1 在实例方法中通过self调用class实例方法获取类对象
[self class]
- 2 通过ViewController类直接调用class类方法获取类对象
[ViewController class]
- 3 在类方法中使用类对象调用class方法获取类对象
+ (Class)classMethod {
return [self class];
}
上面的三种形式我们都在控制台进行输出,输出的结果如下
通过打印,我们发现调用这三个方法,获取到的类对象是同一个类对象,内存地址也是一样的。
这是因为这三个方法调用class方法,打印的都是类对象的isa指针。
NSLog(@"%p, %p, %p", [ViewController classMethod], [ViewController class], [self class]);
打印结果:0x10fc68fd8, 0x10fc68fd8, 0x10fc68fd8
- 4 这个时候我又将其中的一个换成了[person class] 我想看看地址是否会更改,当然答案也是肯定的!
NSLog(@"%p, %p, %p", [ViewController classMethod], [ViewController class], [self class]);
打印结果:0x10fc68fd8 , 0x10fc68fd8 , 0x10fc690a0
那么上面说的这个isa又是什么呢?这个我们又要往深说了。
-
在Objective-C中,任何类的定义都是对象。类和类的实例(对象)没有任何本质上的区别。任何对象都有isa指针,对于oc指针我也进行了实验,图片如下。
-
输出结果如下
所以说通过上面runtime的方式可以通过指针输出你想要的类当中的的全部属性,当然反过来也是可以实现的(这里对runtime不做过多的讲解,改天更新文章再对runtime进行分享)
下面我们说下几种常见的转换方式(大部分的动态反射支持来自NSObject 类。NSObject是所有类(除了一些很少见的例外)的根类。所以基本常用到的类应该都可以支持反射)
- 通过类名的字符串形式实例化对象(这里我拿在项目当中创建的person类进行实验,下面方式属于C语言方法)
Class class="NSClassFormString"(@"person");
person *tea=[[class alloc] init];
- 通过类名来生成相应类的实例
NSString *str=NSStringFormClass(class);
Class * tempClass = NSClassFromString(str);
这里 在创建这个类实例之前 最好判断下 是否该对象存在;
if(!tempClass) return;
// 如果存在 就创建你相应的实例对象 比如上面我们这个类名 是UIViewController子类的类名
UIViewController * tempObj = [[tempClass alloc] init];
-
以上两种情况截图如下
当然反射机制还可以做到下面的两种状态-
- 方法反射之 通过方法名的字符串形式实例化对象
SEL selector=NSSelectorFormString(@"Test");
[person performSelector:selector)];
图片如下-
- 方法反射之 反射成字符串输出
NSString * str = NSStringFormSelector(selector);
以上四种方式就是反射机制常用到的四种形式
本人个人微信公众号地址(喜欢记得关注😯)