`
wsqwsq000
  • 浏览: 676543 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

iphone开发@dynamic的作用

 
阅读更多

 

 

Objective-C 2.0 中增加了@dynamic 指令,表示变量对应的属性访问器方法,是动态实现的,你需要在NSObject 中继承而来的+(BOOL) resolveInstanceMethod:(SEL) sel 方法中指定动态实现的方法或者函数。

Person.h:

 


  1. @interface Person : NSObject{  
  2. NSString *name;  
  3. float weight;  
  4. }  
  5. -(Person*) initWithWeight: (int) weight;  
  6. @property (retain,readwrite) NSString* name;  
  7. @property (readonly)float weight;  
  8. @property float height;  
  9. -(void) print: (NSString*) str;  
  10. @end  


Person.m:

 


  1. void dynamicMethod(id self,SEL _cmd,float w){  
  2. printf("dynamicMethod-%s\n",[NSStringFromSelector(_cmd)  
  3. cStringUsingEncoding:NSUTF8StringEncoding]);  
  4. printf("%f\n",w);  
  5. }  
  6. @implementation Person  
  7. @synthesize name;  
  8. @synthesize weight;  
  9. @dynamic height;  
  10. -(Person*) initWithWeight: (int) w{  
  11. self=[super init];  
  12. if (self) {  
  13. weight=w;  
  14. }  
  15. return self;  
  16. }  
  17. -(void) print: (NSString*) str{  
  18. NSLog(@"%@%@",str,name);  
  19. }  
  20. +(BOOL) resolveInstanceMethod: (SEL) sel{  
  21. NSString *methodName=NSStringFromSelector(sel);  
  22. BOOL result=NO;  
  23. //看看是不是我们要动态实现的方法名称  
  24. if ([methodName isEqualToString:@"setHeight:"]) {  
  25. class_addMethod([self class], sel, (IMP) dynamicMethod,  
  26. "v@:f");  
  27. result=YES;  
  28. }  
  29. return result;  
  30. }  
  31. -(void) dealloc{  
  32. [self setName:nil];  
  33. [super dealloc];  
  34. }  
  35. @end  

 


这里我们对于接口中的height在实现类中使用了@dynamic指令,紧接着,你需要指定一个函数或者其他类的方法作为height的setter、getter方法的运行时实现。为了简单,我们指定了Person.m中定义的函数(注意这是C语言的函数,不是Objective-C的方法)dynamicMethod
作为height的setter方法的运行时实现。被指定为动态实现的方法的dynamicMethod的参数有如下的要求:
A.第一个、第二个参数必须是id、SEL;
B.第三个参数开始,你可以按照原方法(例如:setHeight:(float))的参数定义。
再接下来,你需要覆盖NSObject 的类方法resolveInstanceMethod,这个方法会把需要动态实现的方法(setHeight:)的选择器传递进来,我们判断一下是否是需要动态实现的选择器,如果是就把处理权转交给dynamicMethod。如何转交呢?这里我们就要用到运行时函数class_addMethod(Class,SEL,IMP,char[])。
运行时函数位于objc/runtime.h,正如名字一样,这里面都是C 语言的函数。按照这些函数的功能的不同,主要分为如下几类:操作类型、操作对象、操作协议等。大多数的函数都可以通过名字看出是什么意思,例如:class_addProtocol 动态的为一个类型在运行时增加协议、objc_getProtocol 把一个字符串转换为协议等。具体这些运行时函数都是做什么用的,你可以参看Apple 官方页面:
http://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418
言归正传,我们来解释一下这里需要用到的class_addmethod 方法,这个方法有四个参数,Class 表示你要为哪个类型增加方法,SEL 参数表示你要增加的方法的选择器,IMP 表示你要添加的方法的运行时的具体实现的函数指针。其实在这里你能够看出SEL 并不能在运行时找到真正要调用的方法,IMP 才可以真正的找到实现方法的。
在讲解第四个参数char[]之前,我们先看一下第一篇文档中提到的@encode 指令,在把任意非Objective-C 对象类型封装为NSValue 类型的时候使用到了@encode 指令,但当时我们没有详细说明这个指令的含义。实际上@encode()可以接受任何类型,Objective-C 中用这个指令做类型编码,它可以把任何一个类型转换为字符串,譬如:void 类型被编码之后为v,对象类型为@,SEL 类型为:等,具体的你可以参看Apple 官方页面关于Type Encoding 的描述:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW
现在我们来正式的看以下第四个参数v@:f 的含义,它描述了IMP 指向的函数的描述信息,按照@encode 指令编译之后的字符说明,第一个字符v 表示返回值为void,剩余的字符为dynamicMethod 函数的参数描述,@表示第一个参数id,:自然就是第二个参数SEL,f 就是第三个参数float。由于前面说过动态方法的实现的前两个参数必须是id、SEL,所以第四个参数中的字符串的第二、三个字符一定是@:。我们看到resolveInstanceMethod 方法的返回值为BOOL,也就是这个方法返回YES 表示找到了动态方法的具体实现,否则就表示没有在运行时找到真实的实现,程序就汇报错。
经过了上面的处理,Objective-C 的运行时只要发现你调用了@dynamic 标注的属性的setter、getter 方法,就会自动到resolveInstanceMethod 里去寻找真实的实现。这也就是说你在main.m 中调用peson.height 的时候,实际上dynamicMethod 函数被调用了。实际上除了@dynamic 标注的属性之外,如果你调用了类型中不存在的方法,也会被
resolveInstanceMethod 或者resolveClassMethod 截获,但由于你没有处理,所以会报告不能识别的消息的错误。你可能在感叹一个@dynamic 指令用起来真是麻烦,我也是研究了半天Apple 官方的晦涩的鸟语才搞明白的。不过好在一般Objective-C 的运行时编程用到的并不多,除非你想设计一个动态化的功能,譬如:从网络下载一个升级包,不需要退出原有的程序,就可以动态的替换掉旧的功能等类似的需求。

 

 

分享到:
评论

相关推荐

    iPhone开发实战.pdf

    iPhone开发实战 iPhone开发 iPhone iPhone4 iPhone开发实战 iPhone开发 iPhone iPhone4

    Iphone开发系列源码——Iphone主题源码

    Iphone开发系列源码——Iphone主题源码Iphone开发系列源码——Iphone主题源码Iphone开发系列源码——Iphone主题源码Iphone开发系列源码——Iphone主题源码Iphone开发系列源码——Iphone主题源码Iphone开发系列源码...

    Iphone开发系列源码——iPhone版Wordpress源代码

    Iphone开发系列源码——iPhone版Wordpress源代码Iphone开发系列源码——iPhone版Wordpress源代码Iphone开发系列源码——iPhone版Wordpress源代码Iphone开发系列源码——iPhone版Wordpress源代码Iphone开发系列源码...

    iPhone开发基础教程电子书

    这里推荐两本书《objective-c基础教程》和《iphone开发基础教程》,这两本都是圣经级的巨作,我相信每一个iphone开发人员应该都不会错过这两本书的。  等你xcode和objective-c摸熟之后,或者说,上面提到的那两...

    IPhone对@selector的函数如何传参数

    IPhone对@selector的函数如何传参数

    Iphone开发系列源码——Image图片缩放随着手指

    Iphone开发系列源码——Image图片缩放随着手指Iphone开发系列源码——Image图片缩放随着手指Iphone开发系列源码——Image图片缩放随着手指Iphone开发系列源码——Image图片缩放随着手指Iphone开发系列源码——Image...

    iPhone开发基础教程-PDF版

    iPhone开发,iPhone开发教程,iPhone开发基础教程PDF版

    iPhone开发基础教程

    《iPhone开发基础教程》内容完整丰富,具有较强的通用性,编程领域中各层次读者都能通过《iPhone开发基础教程》快速学习iPhone开发,提高相关技能。iPhone 是一种全新的移动平台,苹果公司为它推出了强大的软件开发...

    iPhone开发入门到精通视频教程

    资源名称:iPhone开发入门到精通视频教程资源目录:【】iOS开发源码系列---工具【】iOS开发源码系列---应用【】iOS开发源码系列---游戏【】iOS开发源码系列---类库与框架【】iOS开发真机测试与发布【】iOS开发视频...

    Iphone开发系列源码——多功能播放器源码

    Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发...

    深入浅出iPhone开发(清晰版,内含中英2个版本的书)

    知名的Head First系列丛书之一,风格与其他Head First系列一脉相承,一定能让读者轻松学会iPhone开发,《深入浅出iPhone开发》是针对iPhone开发的初学者设计的,以几个应用实例的开发为例,循序渐进地对iPhone开发的...

    iphone开发实战

    本书全面探讨了iPhone平台的两种编程方式——Web开发和SDK编程。全在Web开发方面,分别介绍了三个iPhone Web库,即WebKit、iUI和Canvas,并讨论了Web开发环境Dashcode,最后阐述Web应用程序的调试。在SDK开发方面,...

    轻松学iPhone开发

    轻松学iPhone共分3篇。第1篇介绍iPhone的发展、iPhone开发环境以及开发工具的安装过程、iPhone Simulator模拟器

    Iphone开发系列源码——星级评价实现代码

    Iphone开发系列源码——星级评价实现代码Iphone开发系列源码——星级评价实现代码Iphone开发系列源码——星级评价实现代码Iphone开发系列源码——星级评价实现代码Iphone开发系列源码——星级评价实现代码Iphone开发...

    iPhone游戏开发

    iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发iPhone游戏开发

    iphone开发视频教程

    资源名称:iphone开发视频教程资源目录:【】iphone开发视频教程第1集 Mac.OS.X,Cocoa,Touch,Objective-C【】iphone开发视频教程第2集 各种基础的类,功能,对象和实例的介绍【】iphone开发视频教程第3集 如何创建你...

    深入浅出iPhone开发

    《深入浅出iPhone开发》,本书是针对iPhone开发的初学者设计的,以几个应用实例的开发为例,循序渐进地对iPhone开发的各个方面进行了讲解。

    [iphone.开发书籍 高清PDF]iphone3开发基础教程.part3

    [iphone.开发书籍 高清PDF]iphone3开发基础教程.part3

    iPhone3开发基础教程

    这是一本很不错的iphone开发入门级教程

    Iphone开发系列源码——长按实现图标抖动和删除的代码

    Iphone开发系列源码——长按实现图标抖动和删除的代码Iphone开发系列源码——长按实现图标抖动和删除的代码Iphone开发系列源码——长按实现图标抖动和删除的代码Iphone开发系列源码——长按实现图标抖动和删除的代码...

Global site tag (gtag.js) - Google Analytics