iOS開發:Category(分類)和Extension(類擴展)的解惑篇。

Category (分類) 和 Extension (類擴展)的理解和區別:

Category

  • Category解釋、定義
  • Category的用途
  • Category的注意

Extension

  • Extension解釋、定義
  • Extension的作用

*******************************華麗麗的分割線*******************************

Cagegory(分類)解釋、定義

Category:用于向已經存在的類添加方法從而達到擴展已有類的目的,在很多情況下Category也是比創建子類更優的選擇,而新添加的方法也會被被擴展的類的所有子類自動繼承,但是Category原則上無法添加屬性。
先看一下蘋果對Category的解釋:
Category 是表示一個指向分類的結構體的指針,其定義如下:

typedef struct objc_category *Category;
struct objc_category {
    char *category_name                          OBJC2_UNAVAILABLE; // 分類名
    char *class_name                             OBJC2_UNAVAILABLE; // 分類所屬的類名
    struct objc_method_list *instance_methods    OBJC2_UNAVAILABLE; // 實例方法列表
    struct objc_method_list *class_methods       OBJC2_UNAVAILABLE; // 類方法列表
    struct objc_protocol_list *protocols         OBJC2_UNAVAILABLE; // 分類所實現的協議列表
}

通過上面我們可以發現,這個結構體主要包含了分類定義的實例方法與類方法,其中instance_methods 列表是 objc_class 中方法列表的一個子集,而class_methods列表是元類方法列表的一個子集。
但這個結構體里面

根本沒有屬性列表,
根本沒有屬性列表,
根本沒有屬性列表。

Category的用途:

1.在不創建繼承類的情況下實現對已有類的擴展;
2.簡化類的開發工作(當一個類需要多個程序猿協同開發的時候,category可以將同一個類根據用途分別放在不同的源文件中,從而便于程序猿獨立開發相應的方法集合.)
3.將常用的相關方法進行分組;
4.在沒有源代碼的情況下可以用來修復BUG。
5.Category能對大型的類有效分解。通常一個大型類的方法可以根據某種邏輯或是相關性分解為不同的組,一個雷達代碼量越大,將這個類分解到不同的文件中就越顯得有用,每個文件分別是這個類的某些相關的方法的集合。當有多個開發者共同完成一個項目時,每個人所承擔的單獨的category的開發和維護。這樣就版本控制就更加簡單了,因為開發人員之間的工作沖突更少了。
6.當已知某個類庫的某個方法有BUG,我們無法直接修改源代碼的時候,可以使用Category來替代這個已有類中某個方法的實體,從而達到修復BUG的目的。然而卻沒有什么便捷的途徑可以去調用已有類中原有的那個被替換掉方法的實體了。Category通常作為一種組織架構代碼的工具來使用。

Category的注意:

1.分類用于給原有的類添加方法,因為分類在結構體指針中,沒有屬性列表,只有方法列表。所以<原則上講它只能添加方法,不能添加屬性(成員變量),實際上可以通過其它方法添加屬性(我們可以通過runtime手動添加setter/getter方法>
e.g:
在Category的.h文件聲明屬性:

 @property (nonatomic, copy) NSString *sex;

在Category的.m文件使用runtime實現setter/getter方法,這樣外部在訪問分類中的屬性時就不會奔潰,但是在使用_sex時還是會報錯:錯誤提示為:(Use of undeclared identifier '_sex')

static NSString *sexKey = @"SEXKEY";   //定義一個key值
@implementation Programmer (Category)

//運行時實現setter方法
- (void)sex:(NSString *)sex {
    objc_setAssociatedObject(self, & sexKey, sex, OBJC_ASSOCIATION_COPY);
}

//運行時實現getter方法
- (NSString *)sex {
    return objc_getAssociatedObject(self, & sexKey);
}

2.分類中可以寫@property,但是不會生成setter/getter方法,也不會生成實現以及私有的成員變量(編譯時會報警告)
3.可以在分類中訪問原有類.h中的屬性
4.如果分類中有和原類同名的方法,會優先調用分類中的方法,會忽略原有類的方法。同名方法調用的優先級為 分類>本類>父類,因此開發中盡量不要覆蓋原有類方法,除非是原有類方法有BUG。
5.如果多個分類中都有和原有類同名的方法,那么調用該方法的時候調用哪個分類中的方法由編譯器決定,編譯器會執行最后一個參與編譯的分類中的方法。

*******************************華麗麗的分割線*******************************

Extension解釋、定義

Extension是Category的一個特例。類擴展與分類相比只少了分類的名稱,所以也稱之為“匿名分類”
其實開發中,我們每天都在用,對于有些人來說就像是最熟悉的陌生人。
類擴展的格式:

@interface XXX ()
//私有屬性
//私有方法(如果不實現,編譯時會報警,Method definition for 'XXX' not found)
@end

Extension的作用

1.為一個類添加原來沒有的變量、方法、屬性
2.一般的類擴展寫到.m文件中
3.一般的私有屬性寫到.m文件中的類擴展中

Category (分類) 和 Extension (類擴展)的區別:

1.類別中原則上只能添加方法(能添加屬性的原因只是通過runtime解決無setter/getter的問題);
2.類擴展不僅可以增加方法還可以增加屬性,只是該屬性默認是@private(私有)類型的(應用范圍只能在自 身類,而不是子類或其他地方);
3.類擴展中聲明的方法沒有被實現,編譯器會報警,但是類別中的方法沒實現編譯器不會有任何警告。這是因為類擴展是在編譯階段被添加到類中,而類別是在運行時添加到類中的;
4.類擴展不能像類別那樣擁有獨立的實現部分(@implementation部分),也就是說:類擴展聲明的方法必須依托對應類的實現部分來實現;
5.定義在.m中的類擴展方法為私有方法,定義在.h中的類擴展方法為公有的。

總結這篇文章的目的一是為了自己的學習做記錄二是為讀者對分類、類擴展等常見的問題有個清晰的認識,以免在以后被人問起時回答的驢唇不對馬嘴。
RESOURCES

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容