1.category
- 概念理解
category是OC2.0提供的一種語言特性,目的是方便我們對已經存在的類進行擴展 - 應用場景
- 主要作用是為已經存在的類添加方法(在不修改原有類的基礎上進行擴展)
- 可以把類的實現分開在幾個不同的文件里面(對于復雜的類可以按照功能不同分成幾個不同的文件,使用的時候可以按需加載)
- 模擬多重繼承
- 注意點:
- 只能添加方法不能添加成員變量
- category中也可以添加屬性,只不過@property只會生成setter和getter的聲明,不會生成setter和getter的實現以及成員變量
- 如果category中的方法和類中原有方法同名,運行時會優先調用category中的方法
2 extension
- 概念理解
extension又叫延展、擴展,它存在于一個.h文件中,或者寄生在一個類的.m文件中。extension一般用于聲明私有方法,私有屬性,私有成員變量
通常我們使用的時候都是寄生在.m文件中,格式如下
@interface XXXViewController ()
@property (nonatomic, strong) UIView *subView;
@end
3 category和extension的區別
- extension一般用來隱藏類的私有信息,必須有一個類的源碼才能為一個類添加extension,所以你無法為系統的類比如NSString添加extension,除非創建子類再添加extension。而category不需要有類的源碼,我們可以給系統提供的類添加category。
- extension可以添加實例變量,而category不可以。
- extension和category都可以添加屬性,但是category的屬性不能生成成員變量和getter、setter方法的實現。
4 拓展 : +load方法與+initialize
-
load函數調用特點如下:
當類被引用進項目的時候就會執行load函數(在main函數開始執行之前),與這個類是否被用到無關,每個類的load函數只會自動調用一次.由于load函數是系統自動加載的,因此不需要調用父類的load函數,否則父類的load函數會多次執行。- 1.當父類和子類都實現load函數時,父類的load方法執行順序要優先于子類
- 2.當子類未實現load方法時,不會調用父類load方法
- 3.類中的load方法執行順序要優先于類別(Category)
- 4.當有多個類別(Category)都實現了load方法,這幾個load方法都會執行,但執行順序不確定(其執行順序與類別在Compile Sources中出現的順序一致)
- 5.當然當有多個不同的類的時候,每個類load 執行順序與其在Compile Sources出現的順序一致
-
initialize函數調用特點如下:
initialize在類或者其子類的第一個方法被調用前調用。即使類文件被引用進項目,但是沒有使用,initialize不會被調用。由于是系統自動調用,也不需要再調用 [super initialize] ,否則父類的initialize會被多次執行。假如這個類放到代碼中,而這段代碼并沒有被執行,這個函數是不會被執行的。- 1.父類的initialize方法會比子類先執行
- 2.當子類未實現initialize方法時,會調用父類initialize方法,子類實現initialize方法時,會覆蓋父類initialize方(但是initialize系統會自動的隱式調用父類的initialize方法)
- 3.當有多個Category都實現了initialize方法,會覆蓋類中的方法,只執行一個(會執行Compile Sources 列表中最后一個Category 的initialize方法)
-
總結:
- 共同點:
- 父類的調用都在子類的調用之前
- 使用了鎖,都是線程安全的
- 不同點:
- 1)調用的時機不一樣:load是app加載進內存的時候調用了,initialize是當當前類或者子類第一次調用某個方法前調用
- 2)是否調用父類的方法:load是不會去調用父類的load方法,initialize系統默認會先調用父類的initialize方法然后調用子類的,都不需要使用super顯示調用
-3)用途不一樣:load方法執行時機比較早,其他的類可能還沒加載進來,同時load方法是線程安全的,主要用來交換方法的實現;initialize方法主要用來對一些不方便在編譯期初始化的對象進行賦值,比如NSMutableArray這種類型的實例化依賴于runtime的消息發送,所以顯然無法在編譯器初始化。
- 共同點: