需求由来:今天突然接到领导分配的需求,要在之前的项目中加上友盟的统计,统计的需求也很简单,只进行界面统计,以之前的项目经验来看,就是在BaseViewController ,里面把所以的类和类名一一列出来,在ViewDidApper时候发送开始统计的方法,在viewWillDisappear时候再发送结束统计的方法。打开项目瞬间发现,有的继承了BaseViewController,有的直接继承UIViewController,瞬间懵逼了。为了保证统计的完整性,想到的办法 ,要不在没继承BaseViewController的VC里面单独添加统计方法,不过这样太浪费时间了,还有更优的办法就是让没继承BaseViewController,去继承BaseViewController,这样也还可行,但相信还有更佳的方法来解决这个问题。于是便想起了Runtime.
实现原理:Method Swizzling 原理
在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。
每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。
可以利用 method_exchangeImplementations 来交换2个方法中的IMP。
实现步骤:
工程目录如下图:
1.在AppDelegate中引入文件然后激活其方法
2.在AddUMMethod方法中来封装下Method Swizzling的方法实现,由于根据需求不同,有的需要交换类方法,有的需要交换实例方法,为了对两个方法都进行了实现。
3.到这一步就相当于是平时的那个BaseViewController,在新的方法里面去写自己需要写的方法实现了,对于我的需求来说,就是在viewDidAppear方法里去遍历得到当前的VC然后把发送开始统计的方法就完成了。为了方便看出效果在里面创建一个红色的label.
最终效果如图
可以发现ViewController这个方法里面没写一行代码,也没继承任何类,就能成功的实现了方法继承的功能。
源码如下:https://github.com/wanglinchao/InheritWithRuntime