在iOS开发中,category(类目、类别)是一个很好用的东西。(纯文字,短小而精罕)
我们可以给一个类添加方法和属性。好比如NSDateFormatter这玩意每次都new开销是非常大的,这在tableview中的体现尤为明显,有了category我们就可以为他写一个单例,避免了每次都为它开辟新的内存。
于是,我们想,如果用category去重写该类的方法,会怎样?实测可行,果然被覆盖了。。。但是,作为祖国未来的花朵,我们不能这么干!
理由如下:
1、category没有办法去代替子类,它不能像子类一样通过super去调用父类的方法实现。如果category中重写覆盖了当前类中的某个方法,那么这个当前类中的原始方法实现,将永远不会被执行,这在某些方法里是致命的。(ps:这里提一下,+(void)load方法是一个特例,它会在当前类执行完之后再在category中执行。)
2、同时,一个category也不能可靠的覆盖另一个category中相同的类的相同的方法。例如UIViewController+A与UIViewController+B,都重写了viewDidLoad,我们就无法控制谁覆盖了谁。
3、通过观察头文件我们可以发现,Cocoa框架中的许多类都是通过category来实现功能的,可能不经意间你就覆盖了这些方法中的其一,有时候就会产生一些无法排查的异常原因。
4、category的诞生只是为了让开发者更加方便的去拓展一个类,它的初衷并不是让你去改变一个类。
结论:
要重写方法,当然我们首推通过子类重写父类的方法,在一些不方便重写的情况下,我们也可以在category中用runtime进行method swizzling(方法的偷梁换柱)来实现。
网友评论
不过第二点似乎有点小误区:category如果有同一个方法,是可以知道哪个方法执行的,
category的方法会在运行时插入到方法列表的前面.所以根据build phases中的compile source的顺序可以确定~