关于几个判断对象归属及消息可用性的方法
1、类的接口声明:
有自定义的两个类,分别是Square和Rectangle。
其中类接口声明如下所示:
- Rectangle 类接口:
@interface Rectangle : NSObject
-(void)sideOfOb;
@end
Rectangle继承自NSObject。
- Square类接口:
@interface Square : Rectangle
-(void) setWidth: (int) a andHeight: (int) b;
-(void)sideOfOb;
@end
Square类继承自Rectangle。
2、main函数中使用测试函数:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Square* mySquare = [[Square alloc]init];
//------------------------------------------------------------------------
//直接关系 : isMemberOf
//测试某个对象是否是某个类的实例对象:isMemberOf 可以准确识别某个对象的类型归属
if ( [mySquare isMemberOfClass:[Square class]] == YES )
{//调用类的class方法,生成一个类对象,用作isMemberOfClass对象方法的参数
//该对象方法返回一个布尔值
NSLog(@"mySquare is a member of Square class ");
}
if ( [mySquare isMemberOfClass:[Rectangle class]] == YES )
{
NSLog(@"mySquare is a member of Rectangle class");
}
if ([mySquare isMemberOfClass:[NSObject class]] == YES)
{
NSLog(@"mySquear is a member of NSObject class");
}
//------------------------------------------------------------------------
//归属关系 : isKindOf
//测试某个对象的类型:isKindOf 可以准确识别某个对象是某继承链上类的对象
if ([mySquare isKindOfClass:[Square class]] == YES)
{
NSLog(@"mySquare is a kind of Square");
}
if ([mySquare isKindOfClass:[Rectangle class]])
{
NSLog(@"mySquare is a kind of Rectangle");
}
if ([mySquare isKindOfClass:[NSObject class]])
{
NSLog(@"mySquare is a kind of NSObject");
}
//------------------------------------------------------------------------
//在square类中定义setwidthandheight,在Rectangle中定义whensetsied
//测试mySquare对象可以接受哪些消息: respondsToSelector 使用@selector指令来达到目的
//未在square中定义whenSetSide,即使它父类中有这个方法,但是这个测试也是为FALSE。
//继承的对象方法测试不会成功
if ([mySquare respondsToSelector:@selector(sideOfOb:)]) //提示未声明的selector
{
NSLog(@"mySquare responds to whenSetSide: method.");
}
//类中有这个方法,测试成功输出
if ([mySquare respondsToSelector:@selector(setWidth:andHeight:)])
{
NSLog(@"mySquare responds to setSide:andHeight method.");
}
//测试类Square对selector:alloc的反应,成功
//可能是因为Square类中有自动生成的alloc的实现*********************
if ([Square respondsToSelector:@selector(alloc)])
{
NSLog(@"Square class responds to alloc method.");
}
//------------------------------------------------------------------------
//测试类对象支持的方法:instancesRespondsToSelector 类的实例可以接收哪些消息
//测试未成功。是因为没有声明这个selector导致的呢?和PIOC不一致
if ([Square instancesRespondToSelector:@selector(sideOfOb:)])
{
NSLog(@"Instances of Square responds to setSide: method.");
}
if ([Rectangle instancesRespondToSelector:@selector(sideOfOb:)])
{
NSLog(@"Instances of Rectangle responds to setSide: method. ");
}
//测试某个类是否是另外一个类的子类
if ([Square isSubclassOfClass:[Rectangle class]])
{
NSLog(@"Square is a subclass of a rectangle.");
}
}//autoReleasePool...
return 0;
}//main function...
输出结果如下所示:
2016-03-31 13:30:59.405 ask_questions[8535:190806] mySquare is a member of Square class
2016-03-31 13:30:59.406 ask_questions[8535:190806] mySquare is a kind of Square
2016-03-31 13:30:59.406 ask_questions[8535:190806] mySquare is a kind of Rectangle
2016-03-31 13:30:59.407 ask_questions[8535:190806] mySquare is a kind of NSObject
2016-03-31 13:30:59.407 ask_questions[8535:190806] mySquare responds to setSide:andHeight method.
2016-03-31 13:30:59.407 ask_questions[8535:190806] Square class responds to alloc method.
2016-03-31 13:30:59.407 ask_questions[8535:190806] Square is a subclass of a rectangle.
Program ended with exit code: 0
3、说明:
3.1 isMemberOf方法:
测试某个对象是否是某个类的实例对象:isMemberOf 可以准确识别某个对象的类型归属 。
比如上面使用的是
if ( [mySquare isMemberOfClass:[Square class]] == YES )
{//调用类的class方法,生成一个类对象,用作isMemberOfClass对象方法的参数
//该对象方法返回一个布尔值
NSLog(@"mySquare is a member of Square class ");
}
得到的输出为:
2016-03-31 13:30:59.405 ask_questions[8535:190806] mySquare is a member of Square class
但是之后跟上的几条语句都未得到输出,说明这个isMemberOf的功能就是:测试对象直接隶属于哪个类。
3.2 isKindOf方法:
代码如下:
if ([mySquare isKindOfClass:[Square class]] == YES)
{
NSLog(@"mySquare is a kind of Square");
}
if ([mySquare isKindOfClass:[Rectangle class]])
{
NSLog(@"mySquare is a kind of Rectangle");
}
if ([mySquare isKindOfClass:[NSObject class]])
{
NSLog(@"mySquare is a kind of NSObject");
}
这三个判断均有输出:
2016-03-31 13:30:59.406 ask_questions[8535:190806] mySquare is a kind of Square
2016-03-31 13:30:59.406 ask_questions[8535:190806] mySquare is a kind of Rectangle
2016-03-31 13:30:59.407 ask_questions[8535:190806] mySquare is a kind of NSObject
说明isKindOf的功能是:测试某对象是哪族类型的,使用该对象所属类的继承链上的所有类进行测试的话,都会成功。
3.3 respondsToSelector方法
当使用这个方法时:
if ([mySquare respondsToSelector:@selector(setWidth:andHeight:)])
{
NSLog(@"mySquare responds to setSide:andHeight method.");
}
if ([Square respondsToSelector:@selector(alloc)])
{
NSLog(@"Square class responds to alloc method.");
}
对象的respondsToSelector方法主要是用于测试对象能否接受@selector指令所指示的消息。
得到的输出如下:
2016-03-31 13:30:59.407 ask_questions[8535:190806] mySquare responds to setSide:andHeight method.
2016-03-31 13:30:59.407 ask_questions[8535:190806] Square class responds to alloc method.
可以看到,因为在Square类中有这个setWidth:andHeight:,所以测试成功输出。而对Square类进行这个测试,类方法alloc也能成功,说明这个方法可以被对象接收,也能被类接收。
3.4 instancesRespondToSelector方法
if ([Square instancesRespondToSelector:@selector(sideOfOb:)])
{
NSLog(@"Instances of Square responds to setSide: method.");
}
if ([Rectangle instancesRespondToSelector:@selector(sideOfOb:)])
{
NSLog(@"Instances of Rectangle responds to setSide: method. ");
}
上面代码没有产生输出,这个instancesRespondToSelector方法待查。
3.5 isSubClassOfClass方法
这个方法用于测试某个类是否是另一个类在继承链上的子类。
代码如下:
if ([Square isSubclassOfClass:[Rectangle class]])
{
NSLog(@"Square is a subclass of a rectangle.");
}
输出如下:
2016-03-31 13:30:59.407 ask_questions[8535:190806] Square is a subclass of a rectangle.
成功输出,测试成功。
4、关于class方法:
class是一个类方法,当将它和类名合用时,如:
[Rectangle class];
生成的是一个该类(因为类也是一种对象)。一般这个语句都是用在上面条件判断的情况,如:
if ([mySquare isKindOfClass:[Square class]] == YES)
上面的代码中使用[Square class],向Square类发送class消息,生成一个类(实例),作为isKindOfClass的参数。而刚才也说过,这个isKindOfClass是测试这个对象是否是给出的类(这里就是生成的那个类)继承链上类的对象。
5、关于@selector指令:
待查,后续补充。