个人体会:obj-C中的“Class类型变量”比c#中的Object基类还要灵活,可以用它生成任何类型的实例(但是它又不是 NSObject)。而选择器SEL与函数指针IMP,如果非要跟c#扯上关系的话,这二个结合起来,就点类似c#中的反射+委托,可以根据一个方法名称字符串,直接调用方法。
"牛"的基类 Cattle.h
1 | #import <Foundation/Foundation.h> |
3 | @interface Cattle : NSObject { |
7 | - ( void )setLegsCount:( int ) count; |
Cattle.m
07 | NSLog (@ "Hello, I am a cattle, I have %d legs." , legsCount); |
10 | -( void ) setLegsCount:( int ) count |
子类“公牛" Bull.h
01 | #import <Foundation/Foundation.h> |
04 | @interface Bull : Cattle { |
08 | - ( NSString *) getSkinColor; |
09 | - ( void ) setSkinColor:( NSString *) color; |
Bull.m
08 | NSLog (@ "Hello, I am a %@ bull, I have %d legs." , [ self getSkinColor],legsCount); |
11 | -( NSString *) getSkinColor |
16 | - ( void ) setSkinColor:( NSString *) color |
代理类DoProxy.h (关键的代码都在这里)
01 | #import <Foundation/Foundation.h> |
04 | #define SET_SKIN_COLOR @"setSkinColor:" |
05 | #define BULL_CLASS @"Bull" |
06 | #define CATTLE_CLASS @"Cattle" |
09 | @interface DoProxy : NSObject { |
18 | void (*setSkinColor_Func)( id , SEL , NSString *); |
27 | -( void ) doWithCattleId:( id ) aCattle colorParam:( NSString *) color; |
30 | -( void ) functionPointers; |
DoProxy.m
05 | @implementation DoProxy |
11 | cattle[0] = [Cattle new ]; |
13 | bullClass = NSClassFromString (BULL_CLASS); |
15 | cattle[1] = [bullClass new ]; |
16 | cattle[2] = [bullClass new ]; |
18 | say = @selector (saySomething); |
19 | skin = NSSelectorFromString (SET_SKIN_COLOR); |
24 | - ( void ) doWithCattleId:( id ) aCattle colorParam:( NSString *) color |
29 | NSString *myName = NSStringFromSelector (_cmd); |
30 | NSLog (@ "Running in the method of %@" , myName); |
34 | NSString *cattleParamClassName = [aCattle className]; |
37 | if ([cattleParamClassName isEqualToString:BULL_CLASS] || [cattleParamClassName isEqualToString:CATTLE_CLASS]) |
39 | [aCattle setLegsCount:4]; |
40 | if ([aCattle respondsToSelector:skin]) |
42 | [aCattle performSelector:skin withObject:color]; |
46 | NSLog (@ "Hi, I am a %@, have not setSkinColor!" , cattleParamClassName); |
48 | [aCattle performSelector:say]; |
52 | NSString *yourClassName = [aCattle className]; |
53 | NSLog (@ "Hi, you are a %@, but I like cattle or bull!" , yourClassName); |
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" ]; |
67 | - ( void ) functionPointers |
70 | setSkinColor_Func=( void (*)( id , SEL , NSString *)) [cattle[1] methodForSelector:skin]; |
75 | say_Func = [cattle[1] methodForSelector:say]; |
78 | setSkinColor_Func(cattle[1],skin,@ "verbose" ); |
80 | NSLog (@ "Running as a function pointer will be more efficiency!" ); |
83 | say_Func(cattle[1],say); |
测试主函数main()
01 | #import <Foundation/Foundation.h> |
04 | int main ( int argc, const char * argv[]) { |
05 | NSAutoreleasePool * pool = [[ NSAutoreleasePool alloc] init]; |
06 | DoProxy *doProxy = [DoProxy new ]; |
08 | [doProxy setAllIVars]; |
10 | [doProxy functionPointers]; |
运行结果:
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.
原文 http://www.cnblogs.com/TsengYuen/archive/2011/04/20/2022107.html