Category(分類)和Extension(擴(kuò)展)

參考文章:http://www.reibang.com/p/935e966c0c08

一乌奇、Category(分類)

分類就是對(duì)一個(gè)類的功能進(jìn)行擴(kuò)展理朋,讓這個(gè)類能夠適應(yīng)不同情況的需求,在一般的實(shí)際開發(fā)中铣墨,我們都會(huì)對(duì)系統(tǒng)的一些常用類進(jìn)行擴(kuò)展室埋,比如:NSString,Button踏兜,Label等等词顾。
簡(jiǎn)單來(lái)說(shuō)類別是一種為現(xiàn)有的類添加新方法的方式
利用Objective-C的動(dòng)態(tài)運(yùn)行時(shí)分配機(jī)制,Category提供了一種比繼承(inheritance)更為簡(jiǎn)潔的方法來(lái)對(duì)類進(jìn)行擴(kuò)展碱妆,無(wú)需創(chuàng)建對(duì)象類的子類就能為現(xiàn)有的類添加新方法
可以為任何已經(jīng)存在的類添加方法肉盹,包括那些沒有源代碼的類,如系統(tǒng)框架類Foundation疹尾,UIKit等

1.類別的作用

(1)可以將類的實(shí)現(xiàn)分散到多個(gè)不同的文件或者不同的框架中上忍,方便代碼的管理。也可以對(duì)框架提供類的擴(kuò)展(沒有源碼纳本,不能修改)窍蓝。
(2)創(chuàng)建對(duì)私有方法的前向引用:在訪問(wèn)其他類的私有方法時(shí)(私有方法:在.h中沒有聲明,在.m中有方法實(shí)現(xiàn))繁成,編譯器報(bào)錯(cuò)吓笙,這時(shí)使用類別,在添加的類別中聲明這些方法(不必提供方法實(shí)現(xiàn))巾腕,編譯器就不會(huì)再產(chǎn)生警告面睛。
(3)向?qū)ο筇砑臃钦絽f(xié)議:創(chuàng)建一個(gè)NSObject的類別稱為“創(chuàng)建一個(gè)非正式協(xié)議”。因?yàn)樽鸢幔琋SObject是頂級(jí)父類叁鉴,在NSObject中添加了該方法,也就是說(shuō)通過(guò)繼承關(guān)系佛寿,所有的類中都有該方法幌墓。

2.局限性

(1)分類只能增加方法,不能增加成員變量,但是可以通過(guò)運(yùn)行時(shí)來(lái)給分類添加屬性
成員變量和屬性的區(qū)別

聲明一個(gè)屬性:
@property (nonatomic, strong) NSString *myString;       
 聲明一個(gè)成員變量(實(shí)例變量):
@interface MyViewController:UIViewController
 {
    NSString *_myString;
 }
@end

因?yàn)楝F(xiàn)在我們用的編譯器已經(jīng)時(shí)LLVM了常侣,當(dāng)我們聲明一個(gè)屬性時(shí)蜡饵,如果LLVM發(fā)現(xiàn)一個(gè)沒有匹配實(shí)例變量的屬性,  它將為你生成以下劃線開頭的實(shí)例變量 _myString, 所以不再需要為屬性手動(dòng)聲明實(shí)例變量了袭祟;
而且不需要在.m文件中寫@synthesize myString验残;也會(huì)自動(dòng)為你生成setter,getter方法巾乳。
@synthesize的作用就是讓編譯器為你自動(dòng)生成setter與getter方法
在.m文件中可以直接使用_myString實(shí)例變量您没,也可以通過(guò)屬性self.myString兩者都是一樣的,只不過(guò)后者時(shí)通過(guò)調(diào)用_myString的setter/getter方法胆绊。
@synthesize 還有一個(gè)作用氨鹏,可以指定與屬性對(duì)應(yīng)的實(shí)例變量,例如@synthesize myString = xxxx压状;那么self.myString 其實(shí)是操作的實(shí)例變量xxxx仆抵,而不是_myString了。
分類中用@property定義變量种冬,只會(huì)生成變量的getter镣丑,setter方法的聲明,不能生成方法實(shí)現(xiàn)和帶下劃線的成員變量娱两。有沒有解決方案呢莺匠?有,通過(guò)運(yùn)行時(shí)建立關(guān)聯(lián)引用

(2)如果分類和原來(lái)類出現(xiàn)同名的方法十兢,優(yōu)先調(diào)用分類中的方法趣竣,原來(lái)類中的方法會(huì)被忽略,方法調(diào)用的優(yōu)先級(jí)分類較高(最后參與編譯的分類優(yōu)先)旱物,只要有分類就優(yōu)先調(diào)用分類遥缕,不考慮與主類的編譯順序

3.利用運(yùn)行時(shí)來(lái)為分類添加屬性

(1)引入運(yùn)行時(shí)頭文件。

 \#import <objc/runtime.h>

(2)在匿名分類或者頭文件中添加屬性宵呛。

 (區(qū)別是:匿名分類中添加的是私有屬性单匣,只在本類中可以使用,類的實(shí)例中不可以使用宝穗;在分類頭文件中添加的屬性在類的實(shí)例中也可以使用)
    //分類的頭文件
    @interface ClassName (CategoryName)
    //我要添加一個(gè)實(shí)例也可以訪問(wèn)的變量所以就寫在這里了
    @property (nonatomic, strong) NSString *str;
    @end
            
    //匿名分類
    @interface ClassName ()
    
    @end

(3)在實(shí)現(xiàn)里面寫要添加屬性的getter户秤、setter方法

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ù)讽营,分別是:
1.源對(duì)象,
2.關(guān)聯(lián)時(shí)用來(lái)標(biāo)記是哪一個(gè)屬性的key(因?yàn)槟憧赡芤砑雍芏鄬傩裕?3.關(guān)聯(lián)的對(duì)象
4.一個(gè)關(guān)聯(lián)策略
            
用來(lái)標(biāo)記是哪一個(gè)屬性的key常見有三個(gè)寫法泡徙,但代碼效果是一樣的橱鹏,如下:
//利用靜態(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ì)象使用原子性
};

二、繼承

多個(gè)類具有相同的實(shí)例變量和方法時(shí)糖荒,考慮用繼承杉辙。即子類可以繼承父類的相同特性。
和Category的區(qū)別:
1.類別是對(duì)方法的擴(kuò)展捶朵,不能添加成員變量蜘矢。繼承可以在原來(lái)父類的成員變量的基礎(chǔ)上,添加新的成員變量
2.類別只能添加新的方法综看,不能修改和刪除原來(lái)的方法品腹。繼承可以增加、修改和刪除方法红碑。
3.類別不提倡對(duì)原有的方法進(jìn)行重載舞吭;繼承可以通過(guò)使用super對(duì)原來(lái)方法進(jìn)行重載
4.類別可以被繼承,如果一個(gè)父類中定義了類別析珊,那么其子類中也會(huì)繼承此類別羡鸥。
共同點(diǎn):都是給一個(gè)類進(jìn)行擴(kuò)展

三、Extension:類擴(kuò)展

Extension是Category的一個(gè)特例
作用:為一個(gè)類增加私有方法忠寻,屬性或成員變量惧浴,也就是說(shuō)只能在本文件中被使用其名字為匿名(為空),并且新添加的方法一定要予以實(shí)現(xiàn)锡溯。(Category沒有這個(gè)限制)

Extension(延展)的實(shí)現(xiàn):
第一種方法:
通過(guò)延展來(lái)實(shí)現(xiàn)方法的私有赶舆,延展的.h頭文件獨(dú)立。這種方法不能實(shí)現(xiàn)真正的方法私有祭饭,當(dāng)在別的文件中引入延展的.h頭文件芜茵,那么在這個(gè)文件中定義的類的對(duì)象就可以直接調(diào)用在延展中定義所謂 私有方法
第二種實(shí)現(xiàn)延展的方式
延展沒有獨(dú)立的頭文件,在類的實(shí)現(xiàn)文件.m中聲明和實(shí)現(xiàn)延展倡蝙,這種方法可以很好的實(shí)現(xiàn)方法的私有九串,因?yàn)樵贠C中是不能引入.m的文件的
第三種實(shí)現(xiàn)方法
私有方式是在.m文件中的@implementation中直接實(shí)現(xiàn)在@interface中沒有聲明的方法,這樣也可以很好的實(shí)現(xiàn)方法的私有寺鸥,開發(fā)中經(jīng)常用的方式猪钮。

Category和Extension區(qū)別:
1.形式上看:extension是匿名的category
2.extension 中聲明的方法需要在implementation中實(shí)現(xiàn),而catefory不做強(qiáng)制要求
3.extension 可以添加屬性胆建、成員變量烤低,而category 一般不可以。

有人說(shuō)extension 是一個(gè)特殊的category笆载,也有人將extension叫做匿名分類扑馁,但是其實(shí)兩者差別很大涯呻。

extension:
1.在編譯器決議,是類的一部分腻要,在編譯器和頭文件的@interface和實(shí)現(xiàn)文件里的@implement一起形成了一個(gè)完整的類复罐。
2.伴隨著類的產(chǎn)生而產(chǎn)生,也隨著類的消失而消失
3.extension一般用來(lái)隱藏類的私有消失雄家,你必須有一個(gè)類的源碼才能添加一個(gè)類的extension效诅,所以對(duì)于系統(tǒng)一些類,如nsstring趟济,就無(wú)法添加類擴(kuò)展
category:
1.是運(yùn)行期決議的
2.類擴(kuò)展可以添加實(shí)例變量乱投,分類不能添加實(shí)例變量
原因:因?yàn)樵谶\(yùn)行期,對(duì)象的內(nèi)存布局已經(jīng)確定咙好,如果添加實(shí)例變量會(huì)破環(huán)類的內(nèi)部布局篡腌,這對(duì)編譯性語(yǔ)言是災(zāi)難性的。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勾效,一起剝皮案震驚了整個(gè)濱河市嘹悼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌层宫,老刑警劉巖杨伙,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異萌腿,居然都是意外死亡限匣,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門毁菱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)米死,“玉大人,你說(shuō)我怎么就攤上這事贮庞÷屯玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵窗慎,是天一觀的道長(zhǎng)物喷。 經(jīng)常有香客問(wèn)我,道長(zhǎng)遮斥,這世上最難降的妖魔是什么峦失? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮术吗,結(jié)果婚禮上尉辑,老公的妹妹穿的比我還像新娘。我一直安慰自己较屿,他們只是感情好隧魄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布实幕。 她就那樣靜靜地躺著,像睡著了一般堤器。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上末贾,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天闸溃,我揣著相機(jī)與錄音,去河邊找鬼拱撵。 笑死辉川,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拴测。 我是一名探鬼主播乓旗,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼集索!你這毒婦竟也來(lái)了屿愚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤务荆,失蹤者是張志新(化名)和其女友劉穎妆距,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體函匕,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娱据,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盅惜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片中剩。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抒寂,靈堂內(nèi)的尸體忽然破棺而出结啼,到底是詐尸還是另有隱情,我是刑警寧澤蓬推,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布妆棒,位于F島的核電站,受9級(jí)特大地震影響沸伏,放射性物質(zhì)發(fā)生泄漏糕珊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一毅糟、第九天 我趴在偏房一處隱蔽的房頂上張望红选。 院中可真熱鬧,春花似錦姆另、人聲如沸喇肋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蝶防。三九已至甚侣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間间学,已是汗流浹背殷费。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留低葫,地道東北人详羡。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像嘿悬,于是被迫代替她去往敵國(guó)和親实柠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容