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

我们之前说到,想要统计每个页面的启动时间。我们可以知道,每个页面都继承了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方法,用于在加载时替换方法。

swizzle1.png

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

swizzle2.png

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

swizzle2.5.png

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

swizzle3.png

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

swizzle4.png

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,697评论 33 466
  • 继上Runtime梳理(四) 通过前面的学习,我们了解到Objective-C的动态特性:Objective-C不...
    小名一峰阅读 4,110评论 0 3
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,800评论 0 9
  • /* UIViewController is a generic controller base class th...
    DanDanC阅读 5,845评论 0 2
  • 1.margin与百分比单位 2.margin重叠 margin重叠通常特性: 只发生在block水平元素(例如:...
    徐国军_plus阅读 4,755评论 0 2