使用runtime交换系统类方法(神奇的swizzle)
2016-10-18 本文已影响554人
帅裂苍穹的七爷爷
我们之前说到,想要统计每个页面的启动时间。我们可以知道,每个页面都继承了UIViewController,假设每个页面开始启动的时间大概在LoadView的时候,结束启动的时间大概在在ViewDidAppear的时候。
问题1:
应该如何尽量少的改动原有代码实现这个功能呢?
回答:
因为每个页面都继承UIViewController,所以如果我们能够修改UIViewController的LoadView和ViewDidAppear方法就好了。
问题2:
但是UIViewController是系统类,如何修改系统类的实现?
回答:
可以参看我的文章深入浅出理解分类(category)和类扩展(extension),使用分类来重写LoadView和ViewDidAppear方法。同时重写+load方法,在其中实现分类loadView和本类loadView的代码互换。
下面我们可以通过一个例子来看看能否实现交换loadView和UIViewController。
1.创建一个UIViewController的分类。这个交换方法其实原理是runtime,所以要加入头文件<objc/runtime.h>
2.在其中重写LoadView和ViewDidAppear方法,注意不要取和本类同样的名字。然后写一个load方法,用于在加载时替换方法。
![](https://img.haomeiwen.com/i2526647/fc4f3195b4386a1d.png)
3.下面写一下交换方法的函数实现,基本写法是一样的,就写一个+ (void)swizzledLoadViewSel()的实现
![](https://img.haomeiwen.com/i2526647/a2c346572db9186d.png)
4.这个时候还有一件事,在我们写的loadView_Swizzle以及ViewDidAppear_Swizzle中调用本类方法。因为我们不知道系统类怎么实现的,需要先调用父类的方法,再完成自己的实现。
![](https://img.haomeiwen.com/i2526647/f4e17053dec6c123.png)
5.下面让我们测试一下,首先我们有一个默认的ViewController,.m文件如下图所示:
![](https://img.haomeiwen.com/i2526647/c34d2abced29d1ab.png)
6.我们运行一下,看一下控制台:
![](https://img.haomeiwen.com/i2526647/6b99c322c98f32e9.png)