Objective-C的运行时机制,反射机制
1、获取类信息
NSArray等集合对象中不限制所存储的对象类型,只要它是一个NSObject就行,如果想知道我们刚刚放进去的对象是什么类型,可发送class消息:
id class = [[arrayobjectAtIndex:0]class];
2、选择器
选择器@selector,用于查询对象的某个方法。
3、类的动态创建
要在代码中创建类,而不是通过静态的.h和.m文件定义类,可以使用Object C运行时库API(#import<objc/runtime.h>)
Class newClz =objc_allocateClassPair([NSError class],”RuntimeErrorSubclass”,0);
class_addMethod(newClz,@selector(retort), (IMP)ReportFunction, “v@:”);
shiyongobjc_allocateClassPair动态函数创建一个类,并在参数中指明该类的父类和类名。用class_addMethod函数为该类增加了一个方法report,这个方法是由函数ReportFunction实现的,由于该函数至少应包含两个参数self和_cmd,因此该方法有3个参数,类型分别为v、@、:(一个返回值,self,_cmd)。
v代表void,指定了方法的返回值;@代表了id类型(对象),制定了方法的固定参数self;:表示了选择器类型(SEL),指定了固定参数_cmd。因此ReportFunction应当实现为:
voidReportFunction(id self, SEL _cmd)
{
//实现代码
}
新类被注册为类对(Class Pair)
类对注册后,即可在代码中使用
id obj = [[newClzalloc]init];
[objperformSelector:@selector(report)];
[obj release];
4、类的动态加载
Class clz =NSClassFromString(@”MyClass”);
返回对象为“类对象”Class。通过这种方法,从字符串构建类实例就不再是什么问题了
id obj = [[clzalloc]init];
或者
id obj =[[NSClassFromString(@”MyClass”) alloc]init];
这使得我们可以在运行时而不是编译时加载类,同时,不需要#import”MyClass”.
4、方法的动态调用
通过@selector关键字可以在一定程度上实现方法的动态调用。更动态的方式是通过Fundation框架的NSSelectorFromString函数,可以直接从字符串获取一个选择器:
SEL sel =NSSelectorFormString(@”doSonethingMethod:”);
if([objectresponsToSelector:sel]){
[object performSelector:sel withObject:color];
}