经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
Method Swizzling
来源:cnblogs  作者:路人Q  时间:2019/9/26 9:02:18  对本文有异议
  1.  

// Method Swizzling 的最佳实践

  1.  

// 下面我们就以替换 viewWillAppear 方法为例谈谈 Method Swizzling 的最佳实践,话不多说,直接上代码:


  1. @interface UIViewController (MRCUMAnalytics)
  2. @end
  3. @implementation UIViewController (MRCUMAnalytics)
  4. + (void)load {
  5. static dispatch_once_t onceToken;
  6. dispatch_once(&onceToken, ^{
  7. Class class = [self class];
  8. SEL originalSelector = @selector(viewWillAppear:);
  9. SEL swizzledSelector = @selector(mrc_viewWillAppear:);
  10. Method originalMethod = class_getInstanceMethod(class, originalSelector);
  11. Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
  12. BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
  13. if (success) {
  14. class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
  15. } else {
  16. method_exchangeImplementations(originalMethod, swizzledMethod);
  17. }
  18. });
  19. }
  20. #pragma mark - Method Swizzling
  21.  
  22. - (void)mrc_viewWillAppear:(BOOL)animated {
  23. [self mrc_viewWillAppear:animated];
  24. [MobClick beginLogPageView:NSStringFromClass([self class])];
  25. }
  26. @end

 

  1. 为什么是在 +load 方法中实现 Method Swizzling 的逻辑,而不是其他的什么方法,比如 +initialize 等;
  2. 为什么 Method Swizzling 的逻辑需要用 dispatch_once 来进行调度;
  3. 为什么需要调用 class_addMethod 方法,并且以它的结果为依据分别处理两种不同的情况。

下面我们就一起来分析下这三个为什么到底是为了什么?

第 1 个为什么:看过我前面文章《Objective-C +load vs +initialize》 的同学应该知道,+load 和 +initialize 是 Objective-C runtime 会自动调用的两个类方法。但是它们被调用的时机却是有差别的,+load 方法是在类被加载的时候调用的,而 +initialize 方法是在类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用。也就是说 +initialize 方法是以懒加载的方式被调用的,如果程序一直没有给某个类或它的子类发送消息,那么这个类的 +initialize 方法是永远不会被调用的。此外 +load 方法还有一个非常重要的特性,那就是子类、父类和分类中的 +load 方法的实现是被区别对待的。换句话说在 Objective-C runtime 自动调用 +load 方法时,分类中的 +load 方法并不会对主类中的 +load 方法造成覆盖。综上所述,+load 方法是实现 Method Swizzling 逻辑的最佳“场所”。

第 2 个为什么:我们上面提到,+load 方法在类加载的时候会被 runtime 自动调用一次,但是它并没有限制程序员对 +load 方法的手动调用。什么?你说不会有程序员这么干?那可说不定,我还见过手动调用 viewDidLoad 方法的程序员,就是介么任性。而我们所能够做的就是尽可能地保证程序能够在各种情况下正常运行。

第 3 个为什么:我们使用 Method Swizzling 的目的通常都是为了给程序增加功能,而不是完全地替换某个功能,所以我们一般都需要在自定义的实现中调用原始的实现。所以这里就会有两种情况需要我们分别进行处理:

 

推荐参考链接: https://mp.weixin.qq.com/s/n-G9cbjiRwxNzzCO9kOf5w

值得细看一下.非常不错

 

原文链接:http://www.cnblogs.com/lurenq/p/11586547.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号