OC的反射机制

目录
  • 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];
}

上面的三种形式我们都在控制台进行输出,输出的结果如下

OC的反射机制_第1张图片
都是访问当前VC下面class的地址

通过打印,我们发现调用这三个方法,获取到的类对象是同一个类对象,内存地址也是一样的。
这是因为这三个方法调用class方法,打印的都是类对象的isa指针。

NSLog(@"%p, %p, %p", [ViewController classMethod], [ViewController class], [self class]);
打印结果:0x10fc68fd8, 0x10fc68fd8, 0x10fc68fd8

  • 4 这个时候我又将其中的一个换成了[person class] 我想看看地址是否会更改,当然答案也是肯定的!
OC的反射机制_第2张图片
输出截图

NSLog(@"%p, %p, %p", [ViewController classMethod], [ViewController class], [self class]);
打印结果:0x10fc68fd8 , 0x10fc68fd8 , 0x10fc690a0

  那么上面说的这个isa又是什么呢?这个我们又要往深说了。
  • 在Objective-C中,任何类的定义都是对象。类和类的实例(对象)没有任何本质上的区别。任何对象都有isa指针,对于oc指针我也进行了实验,图片如下。


    OC的反射机制_第3张图片
    isa指针
  • 输出结果如下


    OC的反射机制_第4张图片
    person 类下面的全部属性

所以说通过上面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];
  • 以上两种情况截图如下


    OC的反射机制_第5张图片
    通过类名的字符串形式实例化对象 类名转换成字符串
当然反射机制还可以做到下面的两种状态-
  • 方法反射之 通过方法名的字符串形式实例化对象
SEL selector=NSSelectorFormString(@"Test");
 [person  performSelector:selector)];

图片如下-


OC的反射机制_第6张图片
通过方法名的字符串形式实例化对象
OC的反射机制_第7张图片
通过方法名的字符串形式实例化对象
  • 方法反射之 反射成字符串输出
  NSString * str =   NSStringFormSelector(selector);

以上四种方式就是反射机制常用到的四种形式

本人个人微信公众号地址(喜欢记得关注)


OC的反射机制_第8张图片
辛小二个人微信公众号地址

你可能感兴趣的:(OC的反射机制)