避免在category中重写方法

在OC开发中,乃至系统的很多框架里都使用了category(类目、类别)来拓展方法功能。

category扩展的应用场景非常之多,比如大名鼎鼎的WebImageCache就是对UIimageView设置了拓展,我们对UIView设置frame的各个参数的时候也会设置拓展,总之对任何类增加方法的时候我们首先就会想到是否继承,是否拓展。比如NSDateFormatter每次new出来开销是很大的,这在tableview中的体现尤为明显,有了category我们就可以为他写一个单例,避免了每次都为它开辟新的内存。

所以我们会认为,如果用category去重写该类的方法是不是可行呢?实测可行,果然被覆盖了。但是,这里有一些致命的问题。

理由如下:

1、category没有办法去代替子类,它不能像子类一样通过super去调用父类的方法实现。如果category中重写覆盖了当前类中的某个方法,那么这个当前类中的原始方法实现,将永远不会被执行,这在某些方法里是致命的。

2、同时,一个category也不能覆盖另一个category中相同的类的相同的方法。例如UIViewController+A与UIViewController+B,都重写了viewWillAppear,我们就无法知道谁覆盖了谁。

3、通过观察头文件我们可以发现,Cocoa框架中的许多类都是通过category来实现功能的,可能不经意间你就覆盖了这些方法中的其一,有时候就会产生一些无法排查的异常原因。

4、category的诞生只是为了让开发者更加方便的去拓展一个类,它的初衷并不是让你去改变一个类。

结论:

要重写方法,当然我们首推通过子类重写父类的方法,在一些不方便重写的情况下,我们也可以在category中用runtime进行method swizzling(方法的偷梁换柱)来实现。Runtime解析请看:runtime机制利用

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: