一梢夯、Category
Category在iOS開發(fā)中使用頻繁烘挫,尤其在為系統(tǒng)類進(jìn)行拓展的時(shí)候,我們可以不用繼承系統(tǒng)類雳锋,直接給系統(tǒng)類添加方法黄绩,最大程度體現(xiàn)了Objective-C的動(dòng)態(tài)語言特性。
注意事項(xiàng)
1:類別是類的擴(kuò)展玷过,只可以聲明方法爽丹,不可以聲明變量(runtime搞)。并且辛蚊,類別的方法優(yōu)先級(jí)較高粤蝎,可覆蓋原類方法。
2:類別的方法中嚼隘,不可以調(diào)用super方法诽里。--類別的局限
3:category 方法不能覆蓋于同一class 的其它 category中的方法。因?yàn)椴环A(yù)知他們的加載優(yōu)先順序飞蛹,就可能在編譯時(shí)出錯(cuò)谤狡。
使用類別:
1。對(duì)框架提供類的擴(kuò)展(沒有源碼卧檐,不能修改)墓懂。
2。 不想生成一個(gè)新的子類的情況下霉囚,比如對(duì)NSArray 的擴(kuò)展捕仔。
3。方便做項(xiàng)目管理盈罐,可以將一份源碼在多個(gè)地方共享或者做方法版本管理榜跌、多人協(xié)作開發(fā)、用本地版本替換公共版本實(shí)現(xiàn)盅粪。
#import
@interface NSObject (Category)
- (void)myMethod;
@end
使用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來彌補(bǔ)這種不足豆同。
??2.1 @dynamic的作用就是禁止編譯器為@property產(chǎn)生setter和getter方法番刊,有兩種辦法實(shí)現(xiàn)setter和getter方法 1.自己提供setter和getter方法;2.方法動(dòng)態(tài)決議(DynamicMethod Resolution)dynamic參考鏈接http://blog.csdn.net/daydreamingboy/article/details/22682851
??擴(kuò)展@synthesize的作用就是讓編譯器自動(dòng)生成setter和getter方法影锈,還有一個(gè)作用芹务,可以指定與屬性對(duì)應(yīng)的實(shí)例變量,例如@synthesize myButton = xxx; 那么self.myButton其實(shí)是操作的實(shí)例變量xxx精居,而不是_myButton了锄禽。
實(shí)際項(xiàng)目中有這么寫的
@synthesize myButton;
這樣寫了之后,那么編譯器會(huì)自動(dòng)生成myButton的實(shí)例變量靴姿,以及相應(yīng)的getter和setter方法沃但。注意:_myButton這個(gè)實(shí)例變量是不存在的,因?yàn)樽詣?dòng)生成的實(shí)例變量為myButton而不是_myButton佛吓,所以現(xiàn)在@synthesize的作用就相當(dāng)于指定實(shí)例變量宵晚;
如果.m文件中寫了@synthesize myButton;那么生成的實(shí)例變量就是myButton;如果沒寫@synthesize myButton;那么生成的實(shí)例變量就是_myButton
#import
static const voidvoid * 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);
}
增加屬性方法
.h文件
//分類的頭文件
@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end
.m文件
//實(shí)現(xiàn)文件
#import "ClassName + CategoryName.h"
#import <objc/runtime.h>
static void *strKey = &strKey;
@implementation ClassName (CategoryName)
-(void)setStr:(NSString *)str
{
objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}
-(NSString *)str
{
return objc_getAssociatedObject(self, &strKey);
}
@end
在setStr:
方法中使用了一個(gè)objc_setAssociatedObject
的方法淤刃,這個(gè)方法有四個(gè)參數(shù),分別是:源對(duì)象吱型,關(guān)聯(lián)時(shí)的用來標(biāo)記是哪一個(gè)屬性的key(因?yàn)槟憧赡芤砑雍芏鄬傩裕┮菁郑P(guān)聯(lián)的對(duì)象和一個(gè)關(guān)聯(lián)策略。
用來標(biāo)記是哪一個(gè)屬性的key常見有三種寫法津滞,但代碼效果是一樣的铝侵,如下:
//利用靜態(tài)變量地址唯一不變的特性
1、static void *strKey = &strKey;
2触徐、static NSString *strKey = @"strKey";
3咪鲜、static char strKey;
關(guān)聯(lián)策略是個(gè)枚舉值,解釋如下:
enum {
OBJC_ASSOCIATION_ASSIGN = 0, //關(guān)聯(lián)對(duì)象的屬性是弱引用
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //關(guān)聯(lián)對(duì)象的屬性是強(qiáng)引用并且關(guān)聯(lián)對(duì)象不使用原子性
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //關(guān)聯(lián)對(duì)象的屬性是copy并且關(guān)聯(lián)對(duì)象不使用原子性
OBJC_ASSOCIATION_RETAIN = 01401, //關(guān)聯(lián)對(duì)象的屬性是copy并且關(guān)聯(lián)對(duì)象使用原子性
OBJC_ASSOCIATION_COPY = 01403 //關(guān)聯(lián)對(duì)象的屬性是copy并且關(guān)聯(lián)對(duì)象使用原子性
};
http://www.reibang.com/p/3cbab68fb856
類別幾個(gè)作用:
- 擴(kuò)展已有的類撞鹉。
- 引用父類未公開方法疟丙。
- 實(shí)現(xiàn)簡單協(xié)議。
http://www.reibang.com/p/2bf61807b6b3
二鸟雏、Extension
Extension非常像是沒有命名的類別享郊,即匿名類別
作用:
1.能為某個(gè)類附加額外的屬性,成員變量孝鹊,方法聲明
2.一般的擴(kuò)展寫到.m文件中(@implementation的上方)
3.一般的私有屬性寫到類擴(kuò)展
使用格式
@interface Mitchell()
//屬性
//方法
@end
使用Extension注意的點(diǎn):
Extension中的方法必須在@implementaion中實(shí)現(xiàn)炊琉,否則編譯會(huì)報(bào)錯(cuò)。