4.9 动态处理类和对象
使用各种各样的机器人对象时,可能需要判断它们的功能,这时,就需要动态判断对象或类是否支持所需要的方法,这些操作都可以通过NSObject类中定义的一系列方法来实现,由于我们创建的类最终都会以NSObject类为终级父类,所以,我们可以在所有类中使用这些方法。
接下来,我们就讨论一些常用的方法。
■4.9.1 对象类型判断
本节将介绍对象类型判断相关的方法。
1.对象是否为某类的实例
需要判断一个对象是不是某个类的实例时,可以使用如下方法。
-(BOOL) isMemberOfClass:classObject;
我们可以看到,isMemberOfClass:定义为一个实例方法,其中,参数classObject为类对象,可以使用class类方法获取,如“[CRobot class]”。
下面的代码将判断一个对象是不是CRobot类的实例(对象)。
CRobot *robot5 = [[CRobot alloc] init]; BOOL result = [robot5 isMemberOfClass:[CRobot class]];
2.对象是否为某类或其父类的实例
判断一个对象是不是某个类或其父类的实例,可以使用isKindOfClass:方法,它同样定义为实例方法,其定义如下。
-(BOOL) isKindOfClass:classObject;
下面的代码演示了isKindOfClass:方法的使用。
CRobotSoldier *killer = [[CRobotSoldier alloc] init]; BOOL result = [killer isKindOfClass:[CRobot class]];
由于CRobotSoldier是CRobot的子类,所以,result的值也是YES。
3.判断类的继承关系
类方法isSubclassOfClass可以判断一个类是不是某个类的子类。
+(BOOL) isSubclassOfClass:classObject;
下面的代码,会判断CRobotSoldier类是否为CRobot类的子类。
BOOL result = [CRobotSoldier isSubclassOfClass:[CRobot class]];
■4.9.2 方法存在判断
在类中定义的方法分为实例方法和类方法,我们分别使用如下两个方法进行判断类或对象中是不是可以使用指定的方法。
判断实例方法是否存在,我们使用respondsToSelector方法,其定义如下。
-(BOOL) respondsToSelector:selector;
其中的参数selector为SEL类型(选择器类型),我们使用@selector(<方法名>)获取没有参数的方法的SEL类型对象。
下面的代码会判断CRobot类型的对象中是否可以使用work方法。
CRobot *robot5 = [[CRobot alloc] init]; BOOL result = [robot5 respondsToSelector:@selector(work)];
如果我们需要判断的方法包含参数,那么,在@selector()指令中只需要包括方法名、参数名称和冒号即可,并不需要指定参数变量。
判断一个类是否包含类方法时,可以使用如下方法。
+(BOOL) instancesRespondToSelector:selector;
其使用与respondsToSelector:方法类似。
■4.9.3 动态调用方法
如果我们需要动态调用方法,可以使用如下三个实例方法,分别用于调用无参数、一个参数和两个参数的方法。
-(id) performSelector:selector; -(id) performSelector:selector withObject:object; -(id) performSelector:selector withObject:object1 withObject:object2;
这几个方法都会返回id类型的数据,它们是所调用方法的返回结果。
下面的代码就调用了CRobot对象中的move方法,此方法没有返回值,所以,我们也不需要处理performSelector:方法的返回值。
CRobot *robot5 = [[CRobot alloc] init]; robot5.name = @"No.5"; [robot5 performSelector:@selector(move)];