Category在iOS開發(fā)中使用非常頻繁酬核。尤其是在為系統(tǒng)類進(jìn)行拓展的時(shí)候蜜另,我們可以不用繼承系統(tǒng)類,直接給系統(tǒng)類添加方法嫡意,最大程度的體現(xiàn)了Objective-C的動(dòng)態(tài)語(yǔ)言特性举瑰。
#import
@interface NSObject (Category)
- (void)myMethod;
@end
這是一個(gè)最簡(jiǎn)單的Category,作用于NSObject類蔬螟,給NSObject添加了一個(gè)方法此迅。
使用Category需要注意的點(diǎn):
(1) Category的方法不一定非要在@implementation中實(shí)現(xiàn),也可以在其他位置實(shí)現(xiàn)旧巾,但是當(dāng)調(diào)用Category的方法時(shí)耸序,依據(jù)繼承樹沒有找到該方法的實(shí)現(xiàn),程序則會(huì)崩潰鲁猩。
(2) Category理論上不能添加變量坎怪,但是可以使用@dynamic 來(lái)彌補(bǔ)這種不足。 (即運(yùn)行時(shí)Runtime)
#import
static const void * externVariableKey =&externVariableKey;
@implementation NSObject (Category)
@dynamic variable廓握;
- (id) variable
{
return objc_getAssociatedObject(self, externVariableKey);
}
- (void)setVariable:(id) variable
{
objc_setAssociatedObject(self, externVariableKey, variable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-----------------------------------------------------------------------------------------
Extension非常像是沒有命名的類別搅窿。
@interface MyClass : NSObject
@property (retain, readonly) float value;
@end
//一般的時(shí)候,Extension都是放在.m文件中@implementation的上方隙券。
@interface MyClass ()
@property (retain, readwrite) float value;
@end
使用Extension需要注意的點(diǎn):
(1) Extension中的方法必須在@implementation中實(shí)現(xiàn)男应,否則編譯會(huì)報(bào)錯(cuò)。
轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_7ea0400d0101eyj6.html
注意事項(xiàng)
1:類別是類的擴(kuò)展娱仔,只可以聲明方法殉了,不可以聲明變量。并且拟枚,類別的方法優(yōu)先級(jí)較高薪铜,可覆蓋原類方法。
2:類別的方法中恩溅,不可以調(diào)用super方法隔箍。--類別的局限
3:category 方法可能會(huì)覆蓋于同一個(gè)類class 的其它 category 中的方法。但也可能被覆蓋脚乡,因?yàn)椴环A(yù)知他們的加載優(yōu)先順序蜒滩,出現(xiàn)這種情況通常會(huì)在編譯時(shí)出錯(cuò)。如果在一個(gè)開發(fā)的SDK中使用了類別奶稠, 就最好保證類別名不同于使用者的類別名俯艰, 以及類別方法也不同于使用者的類別方法名, 通常通過(guò)加前綴來(lái)做到锌订。
使用類別:
1竹握。對(duì)框架提供類的擴(kuò)展(沒有源碼,不能修改)辆飘。
2啦辐。 不想生成一個(gè)新的子類的情況下谓传,比如對(duì) NSArray 的擴(kuò)展。
3芹关。 方便做項(xiàng)目管理续挟,可以將一份源碼在多個(gè)地方共享或者做方法版本管理、多人協(xié)作開發(fā)侥衬、用本地版本替換公共版本實(shí)現(xiàn)诗祸。
擴(kuò)展:
某些情況下,我們需要聲明一個(gè)@property轴总,它對(duì)外是只讀的(readonly)直颅,而對(duì)內(nèi)是可讀寫的(readwrite),這時(shí)肘习,可以通過(guò)Extensions實(shí)現(xiàn)
// .h
@interface BaseClass : NSObject
@property (readonly) NSString *privateString; // 該.h文件對(duì)外公開
@end
// .m
@interface BaseClass() // 該.m文件對(duì)外是不公開的际乘, 當(dāng)然這里也可以放在專門的一個(gè).h文件中坡倔,但同樣不把這個(gè)文件進(jìn)行公開漂佩。
@property (readwrite) NSString *privateString;
@end
@implementation BaseClass
@synthesize privateString;
//...
@end