使用runtime交换系统类方法(神奇的swizzle)

我们之前说到,想要统计每个页面的启动时间。我们可以知道,每个页面都继承了UIViewController,假设每个页面开始启动的时间大概在LoadView的时候,结束启动的时间大概在在ViewDidAppear的时候。

问题1:

应该如何尽量少的改动原有代码实现这个功能呢?

回答:

因为每个页面都继承UIViewController,所以如果我们能够修改UIViewController的LoadView和ViewDidAppear方法就好了。

问题2:

但是UIViewController是系统类,如何修改系统类的实现?

回答:

可以参看我的文章深入浅出理解分类(category)和类扩展(extension),使用分类来重写LoadView和ViewDidAppear方法。同时重写+load方法,在其中实现分类loadView和本类loadView的代码互换。

下面我们可以通过一个例子来看看能否实现交换loadView和UIViewController。

1.创建一个UIViewController的分类。这个交换方法其实原理是runtime,所以要加入头文件

2.在其中重写LoadView和ViewDidAppear方法,注意不要取和本类同样的名字。然后写一个load方法,用于在加载时替换方法。

使用runtime交换系统类方法(神奇的swizzle)_第1张图片
swizzle1.png

3.下面写一下交换方法的函数实现,基本写法是一样的,就写一个+ (void)swizzledLoadViewSel()的实现

使用runtime交换系统类方法(神奇的swizzle)_第2张图片
swizzle2.png

4.这个时候还有一件事,在我们写的loadView_Swizzle以及ViewDidAppear_Swizzle中调用本类方法。因为我们不知道系统类怎么实现的,需要先调用父类的方法,再完成自己的实现。

使用runtime交换系统类方法(神奇的swizzle)_第3张图片
swizzle2.5.png

5.下面让我们测试一下,首先我们有一个默认的ViewController,.m文件如下图所示:

使用runtime交换系统类方法(神奇的swizzle)_第4张图片
swizzle3.png

6.我们运行一下,看一下控制台:

swizzle4.png

7.可以看出来,我们调用了分类里面写的LoadView和ViewDidLoad中的内容,完成了系统类方法和分类方法的交换。

你可能感兴趣的:(使用runtime交换系统类方法(神奇的swizzle))