category 下稱類別允許你甚至在沒有類源碼的情況下擴充一個類的功能,給它增加方法。
** 這個可以理解為 "mixin" 的一種機制。
主要作用是使相同的方法在沒有繼承關的類中複用。
要使用它需要在類的@interface 檔案中的category 處指名方法的名並在對應的實現檔案中編寫代碼。
但是不能使用 category 為類添加新的執行個體變數。
category 只是一種編譯時間手段,定義在裡面的方法與類的執行個體方法在運行時沒有任何的不同。
#import "ClassName.h"
@interface ClassName ( CategoryName )
// method declarations
@end
因為 category 可能需要使用類的執行個體變數,因此需要import 它擴充的類的interface 檔案。
#import "ClassName+CategoryName.h"
@implementation ClassName ( CategoryName )
// method definitions
@end
category 的實現檔案命名如上面標識的那樣。
category 與類的關係是多對一,即一個類可以有多個不同方法集的擴充,但是一個category 只能被應用於一個類(待確認)
category的幾個典型的應用情境:
1。對架構提供類的擴充(沒有源碼,不能修改)。
2。 不想產生一個新的子類的情況下,比如對 NSArray 的擴充。
3。 方便做專案管理,可以將一份源碼在多個地方共用或者做方法版本管理、多人協作開發、用本地版本替換公用版本實現。
不建議在 category 中覆蓋類中的方法,因為在 category 中的方法不能調用 superClass 的方法(因為沒有中繼資料支援)
category 方法不能覆蓋於同一class 的其它 category 中的方法。因為不法預知他們的載入優先順序,就可能在編譯時間出錯。
對類庫的 category 方法覆蓋對導致整個類庫的行為發生變化,因此調用那些方法的類不知道方法的實現已經發生了變化。
警告:
雖然 category 不限於任何 class ,但是仍然不建議編寫針對 rootClass 的 category. 原因是影響面較大,其它開發人員如果不注意的話就會出問題。
而且類對象也可能調用這些方法,甚至在調用時的 self 指標不是執行個體而是類對象本身。
關於Extensions
類的Extension 可以當作是匿名的 category
那麼有什麼用的,就是定義在裡面的方法不能被其它的 category 覆蓋掉,因為找不到 reference. 用這個來實現某種意義上的 private method.