深入理解Objective-C的Runtime机制

3 篇文章 0 订阅


http://www.csdn.net/article/2015-07-06/2825133-objective-c-runtime/6



深入理解Objective-C的Runtime机制

发表于2015-07-06 11:53| 46846次阅读| 来源CSDN| 19 条评论| 作者刘耀柱

移动开发

Objective-C

开发经验

运行时

面向对象

机制

数据结构


摘要:Objective-C是基于C加入了面向对象特性和消息转发机制的动态语言,除编译器之外,还需用Runtime系统来动态创建类和对象,进行消息发送和转发。本文作者通过分析Apple开源的Runtime代码来深入理解OC的Runtime机制。


三种方法的选择

Runtime提供三种方式来将原来的方法实现代替掉,那该怎样选择它们呢?


  • Method Resolution:由于Method Resolution不能像消息转发那样可以交给其他对象来处理,所以只适用于在原来的类中代替掉。
  • Fast Forwarding:它可以将消息处理转发给其他对象,使用范围更广,不只是限于原来的对象。
  • Normal Forwarding:它跟Fast Forwarding一样可以消息转发,但它能通过NSInvocation对象获取更多消息发送的信息,例如:target、selector、arguments和返回值等信息。


Associated Objects

当使用Category对某个类进行扩展时,有时需要存储属性,Category是不支持的,这时需要使用Associated Objects来给已存在的类Category添加自定义的属性。Associated Objects提供三个API来向对象添加、获取和删除关联值:


  • void objc_setAssociatedObject (id object, const void *key, id value, objc_AssociationPolicy policy )
  • id objc_getAssociatedObject (id object, const void *key )
  • void objc_removeAssociatedObjects (id object )


其中objc_AssociationPolicy是个枚举类型,它可以指定Objc内存管理的引用计数机制。


[cpp] view plaincopy


  1. typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {  
  2.     OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */  
  3.     OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.  
  4.                                             *   The association is not made atomically. */  
  5.     OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied.  
  6.                                             *   The association is not made atomically. */  
  7.     OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object. 
  8.                                             *   The association is made atomically. */  
  9.     OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied. 
  10.                                             *   The association is made atomically. */  
  11. };  


下面有个关于NSObject+AssociatedObject Category添加属性associatedObject的示例代码:

NSObject+AssociatedObject.h


[cpp] view plaincopy


  1. @interface NSObject (AssociatedObject)  
  2. @property (strong, nonatomic) id associatedObject;  
  3. @end  


NSObject+AssociatedObject.m


[cpp] view plaincopy


  1. @implementation NSObject (AssociatedObject)  
  2. - (void)setAssociatedObject:(id)associatedObject  
  3. {  
  4.     objc_setAssociatedObject(self, @selector(associatedObject), associatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
  5. }  
  6. - (id)associatedObject  
  7. {  
  8.     return objc_getAssociatedObject(self, _cmd);  
  9. }  
  10. @end  


Associated Objects的key要求是唯一并且是常量,而SEL是满足这个要求的,所以上面的采用隐藏参数_cmd作为key。

Method Swizzling

Method Swizzling就是在运行时将一个方法的实现代替为另一个方法的实现。如果能够利用好这个技巧,可以写出简洁、有效且维护性更好的代码。可以参考两篇关于Method Swizzling技巧的文章:



Aspect-Oriented Programming(AOP)

类似记录日志、身份验证、缓存等事务非常琐碎,与业务逻辑无关,很多地方都有,又很难抽象出一个模块,这种程序设计问题,业界给它们起了一个名字叫横向关注点(Cross-cutting concern),AOP作用就是分离横向关注点(Cross-cutting concern)来提高模块复用性,它可以在既有的代码添加一些额外的行为(记录日志、身份验证、缓存)而无需修改代码。

危险性

Method Swizzling就像一把瑞士小刀,如果使用得当,它会有效地解决问题。但使用不当,将带来很多麻烦。在stackoverflow上有人已经提出这样一个问题:What are the Dangers of Method Swizzling in Objective C?,它的危险性主要体现以下几个方面:


  • Method swizzling is not atomic
  • Changes behavior of un-owned code
  • Possible naming conflicts
  • Swizzling changes the method's arguments
  • The order of swizzles matters
  • Difficult to understand (looks recursive)
  • Difficult to debug


总结

虽然在平时项目不是经常用到Objective-C的Runtime特性,但当你阅读一些iOS开源项目时,你就会发现很多时候都会用到。所以深入理解Objective-C的Runtime数据结构、消息转发机制有助于你更容易地阅读和学习开源项目。

扩展阅读


作者简介:刘耀柱(@Sam_Lau_Dev),iOS Developer兼业余Designer,参与开发技术前线iOS项目翻译,个人博客:http://www.jianshu.com/users/256fb15baf75/latest_articles,GitHub:https://github.com/samlaudev


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值