DoProxy.m的代码说明
DoProxy.m的代码说明
1. 有了DoProxy.h的说明,DoProxy.m将是一件非常轻松的事情,让我们坚持一下把这个轻松的事情搞定。由于篇幅所限,在这里的简单讲解
2. DoProxy.m代码如下:
3. 1#import"DoProxy.h"
2#import"Cattle.h"
3#import"Bull.h"
4
5@implementationDoProxy
6-(void)setAllIVars
7{
8cattle[0]=[Cattlenew];
9
10bullClass=NSClassFromString(BULL_CLASS);
11cattle[1]=[bullClassnew];
12cattle[2]=[bullClassnew];
13
14say=@selector(saySomething);
15skin=NSSelectorFromString(SET_SKIN_COLOR);
16}
17-(void)SELFuncs
18{
19[selfdoWithCattleId:cattle[0]colorParam:@"brown"];
20[selfdoWithCattleId:cattle[1]colorParam:@"red"];
21[selfdoWithCattleId:cattle[2]colorParam:@"black"];
22[selfdoWithCattleId:selfcolorParam:@"haha"];
23}
24-(void)functionPointers
25{
26setSkinColor_Func=(void(*)(id,SEL,NSString*))[cattle[1]methodForSelector:skin];
27//IMPsetSkinColor_Func=[cattle[1]methodForSelector:skin];
28say_Func=[cattle[1]methodForSelector:say];
29setSkinColor_Func(cattle[1],skin,@"verbose");
30NSLog(@"Runningasafunctionpointerwillbemoreefficiency!");
31say_Func(cattle[1],say);
32}
33-(void)doWithCattleId:(id)aCattlecolorParam:(NSString*)color
34{
35if(notFirstRun==NO)
36{
37NSString*myName=NSStringFromSelector(_cmd);
38NSLog(@"Runninginthemethodof%@",myName);
39notFirstRun=YES;
40}
41
42NSString*cattleParamClassName=[aCattleclassName];
43if([cattleParamClassNameisEqualToString:BULL_CLASS]||
44[cattleParamClassNameisEqualToString:CATTLE_CLASS])
45{
46[aCattlesetLegsCount:4];
47if([aCattlerespondsToSelector:skin])
48{
49[aCattleperformSelector:skinwithObject:color];
50}
51else
52{
53NSLog(@"Hi,Iama%@,havenotsetSkinColor!",cattleParamClassName);
54}
55[aCattleperformSelector:say];
56}
57else
58{
59NSString*yourClassName=[aCattleclassName];
60NSLog(@"Hi,youarea%@,butIlikecattleorbull!",yourClassName);
61}
62}
63@end
4. 第10行代码是通过一个预定义的宏BULL_CLASS取得Bull的Class变量。
5. 第11和12行代码是使用bullClass来初始化我们的cattle实例变量数组的第2和第3个元素。
6. 第14行是通过@selector函数来取得saySomething的SEL变量。
7. 第15行是通过向NSSelectorFromString传递预定义的宏SET_SKIN_COLOR来取得setSkinColor的SEL变量。
8. 第22行,笔者打算“戏弄”一下doWithCattleId,向传递了不合适的参数。
9. 第26行,笔者取得了传统的C语言的函数指针,也是使用了第5.5节所述的第一种取得的方法。
10. 第28行,笔者通过5.5节所述的第二种取得的方法得到了函数指针say_Func。
11. 第29行和31行分别执行了分别在第26行和28行取得的函数指针。
12. 第35行是一个BOOL型的实例变量notFirstRun。当对象被初始化之后,确省的值是NO。第一次执行完毕之后,我们把这个变量设定成为YES,这样就保证了花括号里面的代码只被执行一次。
13. 第37行我们通过_cmd取得了doWithCattleId这个方法名字用于输出。当然同学们在设计方法的提供给别人使用的时候,为了防止使用方法的人把这个方法本身传递进来造成死循环,需要使用_cmd这个系统隐藏的变量判断一下。笔者在这里没有做出判断,这样写从理论上来说存在一定的风险。
14. 第42行,我们通过向对象发送className消息来取得这个对象的类的名字。
15. 第43行和第44行,我们通过NSString的方法isEqualToString来判断取得的类的名字是否在我们事先想象的范围之内,我们只希望接受Bull或者Cattle类的对象。
16. 第46行,本来我们想通过SEL的方式来进行这个牛股的设定,但是由于它的参数不是从NSObject继承下来的,所以我们无法使用。我们会有办法解决这个问题的,我们将在后面的章节里面介绍解决这个问题的方法。
17. 第47行的代码,有一个非常重要NSObject的方法respondsToSelector,通过向对象发送这个消息,加上一个SEL,我们可以知道这个对象是否可以相应这个SEL消息。由于我们的Cattle无法相应setSkinColor消息,所以如果对象是Cattle类生成的话,if语句就是NO所以花括号里面的内容不会得到执行。
18. 第59行,我们通过类的名字发现了一个假冒的Cattle,我们把这个假冒的家伙给揪出来,然后实现了屏幕打印。
http://www.itemperor.com/a/ObjectiveC/231.html
原文链接:http://www.jxszl.com/biancheng/dedecms/446877.html