<Smking>通过Category定义与该类本身的方法名相同时, Category方法会优先于它自身的方法, 所以如果在Category中实现了init方法, 并且直接返回为nil, 则会使得所有使用这个类init的对象都会因为Category的方法而返回为nil.
<根据这个原理可以考虑一下,如何拦截已有的方法,使之不可用,当然如果有办法能遍历出所给对象的所有可支持方法就更利于这个使用了。有空可以深入研究一下。>
Category是ObjC语言中的扩展机制之一,另一个为Protocol。
Category提供一种为某个类添加方法而又不必编写子类的途径。
假设有这样一个类CarInfo:
| #import <Foundation/Foundation.h> @interface CarInfo : NSObject { } -(void)sayCarBrand; @end @implementation CarInfo -(void) sayCarBrand{ NSLog(@"Car brand: Golf"); } @end |
我可以用Category为该类增加新的方法:
| #import <Foundation/Foundation.h> #import "CarInfo.h" @interface CarInfo(CarInfoCategory) -(void)sayCarBrandChinese; @end @implementation CarInfo(CarInfoCategory) -(void)sayCarBrandChinese{ NSLog(@"汽车品牌:高尔夫"); } @end |
这里的Category增加了一个新的方法,用来显示汉字名称。可在其他代码中直接调用,就如同调用CarInfo其他实例方法一样:
| CarInfo *carInfo=[[CarInfo alloc] init]; [carInfo sayCarBrandChinese]; |
这种效果是Java做不到的。这得益于ObjC语言方法调度程序这一特殊机制。
如果方法名称相同会怎样?比如:
| #import <Foundation/Foundation.h> #import "CarInfo.h" @interface CarInfo(CarInfoCategory) -(void)sayCarBrand; @end @implementation CarInfo(CarInfoCategory) -(void)sayCarBrand{ NSLog(@"汽车品牌:高尔夫"); } @end |
再次调用:
| CarInfo *carInfo=[[CarInfo alloc] init]; [carInfo sayCarBrand]; |
会发现,打印的是category中的方法,而不是类的实例方法。因为category优先于类实例方法。
那么是否有这样的能力,比如在category的方法内代码中调用类的实例方法,这样不就可以实现类似Java方法拦截器的功能了么?或者说是方法代理模式。遗憾的是,这样不可以。