Category的主要知識點
1. 擴展類的功能
Category提供了一種比繼承(inheritance)更為簡潔的方法來對class進行擴展,我們可以為任何已經存在的class添加方法(不包括數據成員)卻不需要訪問該class的實現文件。
新添加的方法和原有的方法具有同等的地位,可以訪問class的數據成員,並且完全植入到class的繼承體系之中,子類同樣會繼承新添加的方法。 利用category對類進行擴展可以避免使類的繼承體系過於臃腫,復雜,降低了維護成本。另外,新添加的方法如果和已經存在的方法具有相同的 prototype,那么新添加的方法將會覆蓋已經存在的方法,也就是category使得使得在沒有源文件時修改已存在class的 functionality或者清除bug成為可能,所有該class的對象的行為都將發生變化,這一點是繼承無法達到的。
可以在以下情況使用Category
- 當你在定義類的時候,在某些情況下(例如需求變更),你可能想要為其中的某個或幾個類中添加方法。
- 一個類中包含了許多不同的方法需要實現,而這些方法需要不同團隊的成員實現 (有點意思,不知實踐中效果如何)
- 當你在使用基礎類庫中的類時,你可能希望這些類實現一些你需要的方法。
使用方法:“原類名+Category”的方式命名,例子如下:
(1)定義與實現
NSString+Background.h (給NaviationBar新添加的一個Category)
#import <UIKit/UIKit.h> @interface UINavigationBar (Background) - (void)setNavgationBarBg; @end
NSString+Background.m
#import "UINavigationBar+Background.h" @implementation UINavigationBar (Background) - (void)setNavgationBarBg { UIImage * TitleBarImage = [UIImage imageNamed:@"Navigationbar_bg.png"]; if([self respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) { [self setBackgroundImage:TitleBarImage forBarMetrics:UIBarMetricsDefault]; } } @end
(2)調用
#import NSString+Background.h
2. 模擬私有方法/函數
在.m中,實現私有方法。
Foo.m
#impot Foo.h @interface Foo (private) - (void) testPrivate; @end @implementation Foo - (void) test { [self testPrivate]; } - (void) testPrivate { NSLog(@"testPrivate Executed"); } @end
3.缺點
- Category可以訪問原始類的實例變量,但不能添加變量,如果想添加變量,可以考慮通過繼承創建子類。
- Category可以重載原始類的方法,但不推薦這么做,這么做的后果是你再也不能訪問原來的方法。如果確實要重載,正確的選擇是創建子類
- 名稱沖突,即當類別中的方法與原始類方法名稱沖突時,類別具有更高的優先級。類別方法將完全取代初始方法從而無法再使用初始方法。