在oc的runtime机制内有一类方法是可以用来实现类间的方法替换。解决了我们实际开发中诸多常规手段所无法解决的问题。关于Method Swizzling,这里有一篇介绍基本用法的文章

场景

最近出于某种原因,我翻阅了MJRefresh的源码,其中该库就使用了方法交换策略。
在其UICollectionViewUITableView的类别里我发现该库使用了以下代码。于是分析了下其为何如此做的原因。
使用源码如下:


分析

这里先介绍下load的方法的执行方式。load方法是NSObject的方法,NSObject则是oc里大部分类的基类。只要类被添加到runtime中,load的方法均会被调用,而且只会自动被调用一次(除非你自行有调用了次方法,不过一般不会这样做)。其调用方式是执行顺序是 类 -> 子类 ->分类 ,例如A继承与B会先执行B的load再执行A的load,如果分类实现了load方法也是一样会先执行类的load再执行此类的分类里的load方法。因此,此方法是不会被覆盖。

MJRefresh为了替换oc类tableview大专栏  Swizzling的使用e>和collectionview的reloadData以达到调用其自定义的mj_reloadDataBlock,因此实现了分别定义了类别UITableView(MJRefresh)UICollectionView(MJRefresh)并重写了类方法load。在load方法里MJRefresh做了一件事情就是使用runtime里的method_exchangeImplementations方法来实现用mj_reloadData替换tableviewcollectionview里的reloadData方法。
mj_reloadData的方法里我们看到其为了该方法能既能执行原有的reloadData方法又能执行mj_reloadDataBlock,他先调用了[self mj_reloadData]然后有调用了mj_reloadDataBlock。由于方法被交换过,因此此处的[self mj_reloadData]会调用reloadData方法并不会造成死循环,同时也达到了其目的调用原有的reloadData方法。

但是这里我也发现了一个问题,既然方法交换了,如果你调用了[self mj_reloadData]方法则会变成调用reloadData方法,那样岂不是会达到效果?在这里MJRefresh为了不让你这样做,则是将mj_reloadData做为私有方法,没有公开API,你是无法直接调用到的(当然你想调用还是调用的到的,这里就不多做讨论)。

总结

从此处设计,能看出来method_exchangeImplementations的runtime方法的使用场景以及如何运用的思路。在此做了分析记录,也为以后如果碰到一些类似场景提供一些新的解决思路和方式。

最新文章

  1. Java中字符串的几个实例
  2. WMSYS.WM_CONCAT 函數的用法
  3. java Web应用配置log4j日志记录
  4. 【题解】【排列组合】【素数】【Leetcode】Unique Paths
  5. Android的自动对焦
  6. WCF编程系列(二)了解WCF
  7. 代理服务器基本知识普及代理IP使用方法!
  8. alias, bg, bind, break, builtin, caller, cd, command,
  9. Week5(10月11日):国庆后补课的复杂心情
  10. Cocos2d-x shader学习2: 模糊(Blur)
  11. 【原】Unity Shader VS UDK Material Editor
  12. net.sf.json.JSONException: java.lang.reflect.InvocationTargetException Caused by: java.lang.IllegalArgumentException at java.sql.Date.getHours(Unknown Source)
  13. C# 开机自启动和最小化托盘显示
  14. 移动应用开发者最应该知道的8款SDK
  15. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
  16. jquery源码 整体架构
  17. list集合排序
  18. js方法用来获取路径传参上所带的参数
  19. C++复数运算 重载
  20. Linux磁盘与文件系统管理(一)

热门文章

  1. JS中的let变量
  2. 给select赋值之后,再点击选择下拉值时,显示一值不变的解决
  3. 让几个横向排列的浮动子div居中显示的方法
  4. ILSVRC2012下载
  5. C#Web网站的创建
  6. spark docker java kubernetes 获取cpu内核/线程数问题
  7. sqlserver 时间格式 取年月日时分
  8. Opencv笔记(三)——视频的获取及保存
  9. Distribution
  10. linux下java调用C