1 | #import <Foundation/Foundation.h> |
2 | |
3 | @interface Cattle : NSObject { |
4 | int legsCount; |
5 | } |
6 | - ( void )saySomething; |
7 | - ( void )setLegsCount:( int ) count; |
8 | @end |
01 | #import "Cattle.h" |
02 | |
03 | @implementation Cattle |
04 | |
05 | -( void ) saySomething |
06 | { |
07 | NSLog (@ "Hello, I am a cattle, I have %d legs." , legsCount); |
08 | } |
09 | |
10 | -( void ) setLegsCount:( int ) count |
11 | { |
12 | legsCount = count; |
13 | } |
14 | @end |
01 | #import <Foundation/Foundation.h> |
02 | #import "Cattle.h" |
03 | |
04 | @interface Bull : Cattle { |
05 | NSString *skinColor; |
06 | } |
07 | - ( void )saySomething; |
08 | - ( NSString *) getSkinColor; |
09 | - ( void ) setSkinColor:( NSString *) color; |
10 | @end |
01 | #import "Bull.h" |
02 | |
03 | |
04 | @implementation Bull |
05 | |
06 | -( void ) saySomething |
07 | { |
08 | NSLog (@ "Hello, I am a %@ bull, I have %d legs." , [ self getSkinColor],legsCount); |
09 | } |
10 | |
11 | -( NSString *) getSkinColor |
12 | { |
13 | return skinColor; |
14 | } |
15 | |
16 | - ( void ) setSkinColor:( NSString *) color |
17 | { |
18 | skinColor = color; |
19 | } |
20 | @end |
01 | #import <Foundation/Foundation.h> |
02 | |
03 | //定义几个字符串常量 |
04 | #define SET_SKIN_COLOR @"setSkinColor:" |
05 | #define BULL_CLASS @"Bull" |
06 | #define CATTLE_CLASS @"Cattle" |
07 | |
08 | |
09 | @interface DoProxy : NSObject { |
10 | BOOL notFirstRun; |
11 | |
12 | id cattle[3]; |
13 | //定义二个选择器 |
14 | SEL say; |
15 | SEL skin; |
16 | |
17 | //定义一个函数指针(传统C语言的处理方式) |
18 | void (*setSkinColor_Func)( id , SEL , NSString *); |
19 | |
20 | //定义一个IMP方式的函数指针(obj-C中推荐的方式) |
21 | IMP say_Func; |
22 | |
23 | //定义一个类 |
24 | Class bullClass; |
25 | } |
26 | |
27 | -( void ) doWithCattleId:( id ) aCattle colorParam:( NSString *) color; |
28 | -( void ) setAllIVars; |
29 | -( void ) SELFuncs; |
30 | -( void ) functionPointers; |
31 | |
32 | @end |
01 | #import "DoProxy.h" |
02 | #import "Cattle.h" |
03 | #import "Bull.h" |
04 | |
05 | @implementation DoProxy |
06 | |
07 | |
08 | //初始化所有变量 |
09 | - ( void ) setAllIVars |
10 | { |
11 | cattle[0] = [Cattle new ]; |
12 | |
13 | bullClass = NSClassFromString (BULL_CLASS); |
14 | //即cattle[1],cattle[2]都是Bull类的实例 |
15 | cattle[1] = [bullClass new ]; |
16 | cattle[2] = [bullClass new ]; |
17 | |
18 | say = @selector (saySomething); |
19 | skin = NSSelectorFromString (SET_SKIN_COLOR); |
20 | } |
21 | |
22 | |
23 | //初始化id |
24 | - ( void ) doWithCattleId:( id ) aCattle colorParam:( NSString *) color |
25 | { |
26 | //第一次运行的时候 |
27 | if (notFirstRun == NO ) |
28 | { |
29 | NSString *myName = NSStringFromSelector (_cmd); //取得当前正在执行的方法的名字 |
30 | NSLog (@ "Running in the method of %@" , myName); |
31 | notFirstRun = YES ; //修改初次运行标志位 |
32 | } |
33 | |
34 | NSString *cattleParamClassName = [aCattle className]; //取得aCattle的"类名称" |
35 | |
36 | //如果aCattle是Bull或Cattle类的实例 |
37 | if ([cattleParamClassName isEqualToString:BULL_CLASS] || [cattleParamClassName isEqualToString:CATTLE_CLASS]) |
38 | { |
39 | [aCattle setLegsCount:4]; //设置牛的4条腿 |
40 | if ([aCattle respondsToSelector:skin]) //如果aCattle对应的是类中,有定义方法"setSkinColor" |
41 | { |
42 | [aCattle performSelector:skin withObject:color]; //则调用setSkinColor方法 |
43 | } |
44 | else |
45 | { |
46 | NSLog (@ "Hi, I am a %@, have not setSkinColor!" , cattleParamClassName); //否则输出相应的提示信息 |
47 | } |
48 | [aCattle performSelector:say]; //最后执行saySomething方法(这二个方法在Bull与Cattle类中都有,所以肯定能运行) |
49 | } |
50 | else //如果aCattle即不是Bull类也不是Cattle类的实例 |
51 | { |
52 | NSString *yourClassName = [aCattle className]; |
53 | NSLog (@ "Hi, you are a %@, but I like cattle or bull!" , yourClassName); //显示这个"异类"的相关信息 |
54 | } |
55 | } |
56 | |
57 | //初始化选择器以及相应函数 |
58 | - ( void ) SELFuncs |
59 | { |
60 | [ self doWithCattleId:cattle[0] colorParam:@ "brown" ]; |
61 | [ self doWithCattleId:cattle[1] colorParam:@ "red" ]; |
62 | [ self doWithCattleId:cattle[2] colorParam:@ "black" ]; |
63 | [ self doWithCattleId: self colorParam:@ "haha" ]; //这里故意传入一个异类self(即DoProxy本身),DoProxy当然不是Bull或Cattle |
64 | } |
65 | |
66 | //函数指针测试 |
67 | - ( void ) functionPointers |
68 | { |
69 | //取得函数指针的第一种方式 |
70 | setSkinColor_Func=( void (*)( id , SEL , NSString *)) [cattle[1] methodForSelector:skin]; |
71 | //上面的语句其实等效于下面这种方法 |
72 | //IMP setSkinColor_Func = [cattle[1] methodForSelector:skin]; |
73 | |
74 | //用第二种方法取得saySomething的函数指针 |
75 | say_Func = [cattle[1] methodForSelector:say]; |
76 | |
77 | //用函数指针的形式调用setSkinColor |
78 | setSkinColor_Func(cattle[1],skin,@ "verbose" ); |
79 | |
80 | NSLog (@ "Running as a function pointer will be more efficiency!" ); |
81 | |
82 | //调用saySomething方法 |
83 | say_Func(cattle[1],say); |
84 | } |
85 | |
86 | @end |
01 | #import <Foundation/Foundation.h> |
02 | #import "DoProxy.h" |
03 | |
04 | int main ( int argc, const char * argv[]) { |
05 | NSAutoreleasePool * pool = [[ NSAutoreleasePool alloc] init]; |
06 | DoProxy *doProxy = [DoProxy new ]; |
07 | |
08 | [doProxy setAllIVars]; |
09 | [doProxy SELFuncs]; |
10 | [doProxy functionPointers]; |
11 | |
12 | [doProxy release]; |
13 | [pool drain]; |
14 | return 0; |
15 | } |
运行结果:
2011-02-28 21:40:33.240 HelloSelector[630:a0f] Running in the method of doWithCattleId:colorParam:
2011-02-28 21:40:33.245 HelloSelector[630:a0f] Hi, I am a Cattle, have not setSkinColor!
2011-02-28 21:40:33.247 HelloSelector[630:a0f] Hello, I am a cattle, I have 4 legs.
2011-02-28 21:40:33.248 HelloSelector[630:a0f] Hello, I am a red bull, I have 4 legs.
2011-02-28 21:40:33.250 HelloSelector[630:a0f] Hello, I am a black bull, I have 4 legs.
2011-02-28 21:40:33.251 HelloSelector[630:a0f] Hi, you are a DoProxy, but I like cattle or bull!
2011-02-28 21:40:33.252 HelloSelector[630:a0f] Running as a function pointer will be more efficiency!
2011-02-28 21:40:33.254 HelloSelector[630:a0f] Hello, I am a verbose bull, I have 4 legs.