iOS類別(Category)與擴展(Extension,匿名類別)

一、Category

Category在iOS開發(fā)中使用頻繁,尤其在為系統(tǒng)類進行拓展的時候,我們可以不用繼承系統(tǒng)類,直接給系統(tǒng)類添加方法,最大程度體現(xiàn)了Objective-C的動態(tài)語言特性。

注意事項

1:類別是類的擴展,只可以聲明方法,不可以聲明變量(runtime搞)。并且,類別的方法優(yōu)先級較高,可覆蓋原類方法。

2:類別的方法中,不可以調(diào)用super方法。--類別的局限

3:category 方法不能覆蓋于同一class 的其它 category中的方法。因為不法預(yù)知他們的加載優(yōu)先順序,就可能在編譯時出錯。

使用類別:

1。對框架提供類的擴展(沒有源碼,不能修改)。

2。 不想生成一個新的子類的情況下,比如對NSArray 的擴展。

3。方便做項目管理,可以將一份源碼在多個地方共享或者做方法版本管理、多人協(xié)作開發(fā)、用本地版本替換公共版本實現(xiàn)。

#import  
@interface NSObject (Category)  
- (void)myMethod;  
@end 

使用Category需要注意的點:
1.Category的方法不一定非要在@implementation中實現(xiàn),也可以在其他位置實現(xiàn),但是當調(diào)用Category的方法時,依據(jù)繼承樹沒有找到該方法的實現(xiàn),程序會崩潰。
2.Category理論上不能添加變量,但是可以使用@dynamic來彌補這種不足。
??2.1 @dynamic的作用就是禁止編譯器為@property產(chǎn)生setter和getter方法,有兩種辦法實現(xiàn)setter和getter方法 1.自己提供setter和getter方法;2.方法動態(tài)決議(DynamicMethod Resolution)dynamic參考鏈接http://blog.csdn.net/daydreamingboy/article/details/22682851
??擴展@synthesize的作用就是讓編譯器自動生成setter和getter方法,還有一個作用,可以指定與屬性對應(yīng)的實例變量,例如@synthesize myButton = xxx; 那么self.myButton其實是操作的實例變量xxx,而不是_myButton了。
實際項目中有這么寫的

@synthesize myButton;

這樣寫了之后,那么編譯器會自動生成myButton的實例變量,以及相應(yīng)的getter和setter方法。注意:_myButton這個實例變量是不存在的,因為自動生成的實例變量為myButton而不是_myButton,所以現(xiàn)在@synthesize的作用就相當于指定實例變量;
如果.m文件中寫了@synthesize myButton;那么生成的實例變量就是myButton;如果沒寫@synthesize myButton;那么生成的實例變量就是_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文件

//實現(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:方法中使用了一個objc_setAssociatedObject的方法,這個方法有四個參數(shù),分別是:源對象,關(guān)聯(lián)時的用來標記是哪一個屬性的key(因為你可能要添加很多屬性),關(guān)聯(lián)的對象和一個關(guān)聯(lián)策略。

用來標記是哪一個屬性的key常見有三種寫法,但代碼效果是一樣的,如下:

//利用靜態(tài)變量地址唯一不變的特性
1、static void *strKey = &strKey;

2、static NSString *strKey = @"strKey"; 

3、static char strKey;

關(guān)聯(lián)策略是個枚舉值,解釋如下:

enum {
    OBJC_ASSOCIATION_ASSIGN = 0, //關(guān)聯(lián)對象的屬性是弱引用 

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //關(guān)聯(lián)對象的屬性是強引用并且關(guān)聯(lián)對象不使用原子性

    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象不使用原子性

    OBJC_ASSOCIATION_RETAIN = 01401, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性

    OBJC_ASSOCIATION_COPY = 01403 //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
};

http://www.itdecent.cn/p/3cbab68fb856

類別幾個作用:

二、Extension

Extension非常像是沒有命名的類別,即匿名類別
作用:
1.能為某個類附加額外的屬性,成員變量,方法聲明
2.一般的擴展寫到.m文件中(@implementation的上方)
3.一般的私有屬性寫到類擴展

使用格式

@interface Mitchell()
//屬性
//方法
@end

使用Extension注意的點:
Extension中的方法必須在@implementaion中實現(xiàn),否則編譯會報錯。

三、Category和Extension區(qū)別

區(qū)別.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 重點掌握 3 類對象和方法 對象就是一個物體 類的獨特存在就是一個實例,對實例進行操作叫做方法。方法可以應(yīng)用于類或...
    Coder大雄閱讀 1,368評論 0 2
  • 電路如人生 ——由電路得到的啟示 福建信息職業(yè)技術(shù)學(xué)院 朱麗華 每次在介紹和分析《模擬電子線路》課程時,都有個很...
    zhujulie閱讀 3,045評論 8 6
  • 我的父親出生于二十世紀四十年代初,中專肄業(yè),曾經(jīng)當過兵,后來在煤礦上工作,直到退休。 那時的父親,并沒有現(xiàn)代家庭教...
    泠風(fēng)思語閱讀 386評論 0 1
  • 愛不愛你, 喜不喜歡你, 日久見人心的角逐, 水落石出的美麗。 似是而非的不對你有一絲關(guān)心, 那是想要掩飾我對你心...
    阿俊xi閱讀 345評論 0 2
  • 懷月心傷傷月圓, 煮酒邀月月不言。 想是時久久難記, 羿思化古古作田。
    文子的小小事閱讀 296評論 1 3

友情鏈接更多精彩內(nèi)容