OC反射机制

反射机制定义:

运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能就是反射机制.

oc也提供了反射机制,这种动态编程机制可以让oc语言更加灵活。oc提供了三种编程方式与运行环境交互。

第一种:直接通过oc的源代码。这是最常见的方式,运行环境负责在后台工作。当编译代码时,编译器会创建大量数据结构和实现了动态机制的函数,其中数据结构负责保存类、类别中定义的数据,函数负责处理方法调用

第二种:通过nsobject类中定义的方法进行动态编程。我们定义了绝大部份类都是nsobject的子类(nsproxy例外),所以所有的对象都可直接调用nsobject的方法来编译。在少数情况下,nsobject只提供了方法模版,并没有为方法实现提供代码。

第三种:直接调用运行时函数进行动态编程。运行时系统是一个动态共享库,这些都是c的,并不是oc编程必须的,但有些函数在oc编程中也是有用的。

获得class

1、使用Class NSClassFromString(NSString * aClassName)函数来获取,需要传入字符串参数,该字符串的值是某个类的类名。

2、调用某个类的class方法来获取。[Person class]返回的是Person类对应的Class。

3、调用某个对象的class方法,该方法是NSObject类中的一个方法。所以所以OC对象都可以调用该方法

第二种方法的优势:

1、代码更安全,程序在编译阶段就可以检测需要访问的Class对象是否存在

2、程序性能高,因为这个方式无须调用方法。

Class clazz = NSClassFromString(@"NSDate");

NSLog(@"%@",class); // NSDate

id date =[ [clazz alloc]init];
NSLog(@"%@",[date class]); //_NSDate ===>>> oc 很多设计都是采用类簇的,NSDate只是这个类簇的前端,当程序调用[[NSDate alloc]init];创建对象时,程序返回的只是NSDate的子类的实例,而不是NSDate的实例。

NSLog(@"%d",class == NSDate.class); // 1

检查继承关系

如果程序只是需要确认一个类的继承关系,可以直接调用NSObject提供的方式来进行判断。

1、isKindOfClass:需要传入一个Class参数,用于判断该对象是否为该类及其子类的实例

2、isMemberOfClass:需要传入一个Class参数,用于判断该对象是否为该类的实例

3、conformsToProtocol:需要传入一个Protocol参数,用于判断该对象是否为该类及其子类的实例(该方法中需要传入一个Protocol参数,在程序中有两种方法可以获得:①oc提供的@protocol指令来实现;②调用Protocol *NSProtocolFromString(NSString *namestr);方法根据协议名字符串来获取对应的协议)

动态调用方法

#import 
//定义类的接口部分
@interface Perosn : NSObject

@end
#import "Perosn.h"
#import 
#import 

//提供实现部分
@implementation Perosn

- (void)move:(NSNumber *)count
{
    int num = [count intValue];
    for (int i = 0; i < num; i ++) {
        NSLog(@"%@",[NSString stringWithFormat:@"人走在路上~~%d", i]);
    }
}

- (double)addSpeed:(double)factor
{
    //此处希望能动态调用move方法
    //使用performSelector:动态调用move:方法
    [self performSelector:@selector(move:) withObject:[NSNumber numberWithInt:2]];
    [self performSelector:NSSelectorFromString(@"move:") withObject:[NSNumber numberWithInt:2]];
    //使用objc_msgSend()函数动态调用move:方法
    objc_msgSend(self, @selector(move:),[NSNumber numberWithInt:3]);
    objc_msgSend(self, NSSelectorFromString(@"move:"),[NSNumber numberWithInt:3]);
    return 100 *factor;
}
@end

使用objc_msgSend可能报错
//objc_msgSend()报错Too many arguments to function call ,expected 0,have3
解决方法
//Build Setting--> Apple LLVM - Preprocessing--> Enable Strict Checking of objc_msgSend Calls 改为 NO

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