使用id 这个泛型对象,假如别人传递给你一个id,你如何动态判断这个在
运行时传递过来的对象到底有没有XXX()方法呢?因为id 可以代表任意对象,你也不知道运
行时传递的这个id 里面到底有什么东西。其实NSObject中有一系列这样的方法用于动态判
定,类似于JAVA的反射机制,但是Objective-C的用起来更为简单。
01 |
-( BOOL )
isMemberOfClass: (Class) clazz |
04 |
-( BOOL )
isKindOfClass: (Class) clazz |
07 |
-( BOOL )
respondsToSelector: (SEL) selector |
10 |
+( BOOL )
instancesRespondToSelector: (SEL) selector |
13 |
-
(id) performSelector: (SEL) selector |
上面的后三个方法中都涉及到了一个新类型选择器SEL,它用于表示Objective-C的一个方法,
我们知道在C语言中有函数指针指向一个函数,也就是Objective-C的选择器就相当于C语
言中的函数指针,只不过选择器只能表示Objective-C类型中定义的方法。选择器使用
@selector(方法名)的形式获取,例如:@selector(initWithWidth:andHeight:) 、
@selector(alloc)。同时,SEL是在继Class、id 之后第三个不需要在变量前使用*的类型,
因为它已经是一个指针。
另外,注意上面的红色文字,你可以看到这两行的方法都是-开头的,也就是成员方法,但
是为什么类也可以去掉用呢?其实是类的Class对象去掉用的,因为Class对象有着两个方法
的回应能力。
我们以矩形、正方形的程序为基础,进行代码演示。
01 |
int main( int argc, const char *argv[]){
|
02 |
MyRectangle
*rec=[[MyRectangle alloc] initWithWidth: 2 andHeight: 5]; |
04 |
MySquare
*squa=[[MySquare alloc] initWithSize: 6]; |
08 |
if ([squa
isMemberOfClass: [MyRectangle class ]]){
|
09 |
printf ( "squa
isMemberOfClass MyRectangle\n" );
|
11 |
printf ( "squa
not isMemberOfClass MyRectangle\n" );
|
14 |
if ([squa
isMemberOfClass: [MySquare class ]]){
|
15 |
printf ( "squa
isMemberOfClass MySquare\n" );
|
17 |
printf ( "squa
not isMemberOfClass MySquare\n" );
|
19 |
printf ( "----------------------------------------------\n" );
|
22 |
if ([squa
isKindOfClass: [MyRectangle class ]]){
|
23 |
printf ( "squa
isKindOfClass MyRectangle\n" );
|
25 |
printf ( "squa
not isKindOfClass MyRectangle\n" );
|
28 |
if ([squa
isKindOfClass: [MySquare class ]]){
|
29 |
printf ( "squa
isKindOfClass MySquare\n" );
|
31 |
printf ( "squa
not isKindOfClass MySquare\n" );
|
33 |
printf ( "----------------------------------------------\n" );
|
37 |
if ([squa
respondsToSelector: @selector(initWithSize:)]){ |
38 |
printf ( "squa
respondsToSelector initWithSize:\n" );
|
40 |
printf ( "squa
not respondsToSelector initWithSize:\n" );
|
43 |
if ([MySquare
respondsToSelector: @selector(alloc)]){ |
44 |
printf ( "MySquare
respondsToSelector alloc\n" );
|
46 |
printf ( "MySquare
not respondsToSelector alloc\n" );
|
49 |
if ([rec
respondsToSelector: @selector(initWithWidth:andHeight:)]){ |
50 |
printf ( "rec
respondsToSelector initWithWidth:andHeight:\n" );
|
52 |
printf ( "rec
not respondsToSelector initWithWidth:andHeight:\n" );
|
54 |
printf ( "----------------------------------------------\n" );
|
57 |
if ([MySquare
instancesRespondToSelector: @selector(initWithSize:)]){ |
58 |
printf ( "MySquare
instancesRespondToSelector initWithSize:\n" );
|
60 |
printf ( "MySquare
not instancesRespondToSelector initWithSize:\n" );
|
63 |
if ([MySquare
instancesRespondToSelector: @selector(alloc)]){ |
64 |
printf ( "MySquare
instancesRespondToSelector alloc\n" );
|
66 |
printf ( "MySquare
not instancesRespondToSelector alloc\n" );
|
68 |
printf ( "----------------------------------------------\n" );
|
71 |
id
x_id=[rec performSelector: @selector(area)]; |
72 |
[MyRectangle
performSelector: @selector(alloc)]; |
@import url(http://www.cppblog.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);