1.OC基于动态运行时的类型,而c++基于静态类型,也就是说OC编写的程序不能直接编译成可令机器读懂的机器语言(二进制编码),而是在你程序运行时,通过运行时(runTime)把程序编译成可令机器读懂的机器语言;用c++编写的程序,编译时就直接编译成了可令机器读懂的机器语言,这就是为什么把OC视为一门动态开发语言的原因。
OC语言的动态性主要体现在三个方面:动态类型(Dynamic typing)、动态绑定(Dynamic binding)和动态加载(Dynamic loading)。动态类型识别方法(面向对象语言的内省Introspection特性)
1.首先是Class类型:
Class class = [NSObject class]; // 通过类名得到对应的Class动态类型
Class class = [obj class]; // 通过实例对象得到对应的Class动态类型
if([obj1 class] == [obj2 class]) // 判断是不是相同类型的实例
2.Class动态类型和类名字符串的相互转换:
NSClassFromString(@”NSObject”); // 由类名字符串得到Class动态类型
NSStringFromClass([NSObject class]); // 由类名的动态类型得到类名字符串
NSStringFromClass([obj class]); // 由对象的动态类型得到类名字符串
3.判断对象是否属于某种动态类型:
-(BOOL)isKindOfClass:class // 判断某个对象是否是动态类型class的实例或其子类的实例
-(BOOL)isMemberOfClass:class // 与isKindOfClass不同的是,这里只判断某个对象是否是class类型的实例,不放宽到其子类
4.判断类中是否有对应的方法:
-(BOOL)respondsTosSelector:(SEL)selector // 类中是否有这个类方法
-(BOOL)instancesRespondToSelector:(SEL)selector // 类中是否有这个实例方法
区别:
上面两个方法都可以通过类名调用,前者判断类中是否有对应的类方法(通过‘+’修饰定义的方法),后者判断类中是否有对应的实例方法(通过‘-’修饰定义的方法)。此外,前者respondsTosSelector函数还可以被类的实例对象调用,效果等同于直接用类名调用后者instancesRespondToSelector函数。
举个例子:假设有一个类Test,有它的一个实例对象test,Test类中定义了一个类函数:+ (void)classFun;和一个实例函数:- (void)objFunc;,那么各种调用情况的结果如下:
[1][Test instancesRespondToSelector:@selector(objFunc)];//YES
[2][Test instancesRespondToSelector:@selector(classFunc)];//NO
[3][Test respondsToSelector:@selector(objFunc)];//NO
[4][Test respondsToSelector:@selector(classFunc)];//YES
[5][test respondsToSelector:@selector(objFunc)];//YES
[6][test respondsToSelector:@selector(classFunc)];//NO
结论: 如果想判断一个类中是否有某个类方法,应该使用[4]; 如果想判断一个类中是否有某个实例方法,可以使用[1]或者[5]。