Category
無論一個類設計的如何完美,都不可避免的會遇到沒有預測到的需求,那怎么擴展現有的類呢?當然,繼承是個不錯的選擇。但是Objective-C提供了一種特別的方式來擴展類,叫Catagory,可以動態的為已經存在的類添加新的行為。這樣可以保證類的原原來的基礎上,較小的改動就可以增加需要的功能。使用Category對類進行擴展時,不需要訪問其源代碼,也不需要創建子類,這樣我們可以擴展系統提供的類。Category使用簡單的方式,實現了類的相關方法的模塊化,把不同的類方法分配到不同的分類文件中。
通過一個簡單的例子看看Category如何使用。
現在我們有一個類叫MyClass
?
好了,有了上面的MyClass后,我們要在不增加子類,不修改MyClass類的情況下增加一個HelloWorld的方法,怎么添加呢?只需添加兩個文件MyClass+HelloWorld.h ?和?MyClass+HelloWorld.m。
在聲明文件和實現文件中用“()”把Category的名稱括起來。原類名+Category”的這是約定的文件命名方式。
Category on的類是MyClass,選對了哦
這樣Xcode就幫你創建了MyClass+HelloWorld.h ?和?MyClass+HelloWorld.m這兩個文件了。
那么我們現在添加一個HelloWorld方法。看看實現后的代碼如下:
?
?
?
?
運行打印結果:
?
?
那的Category的使用場景有那些呢:
1、類包含了很多個方法實現,而這些方法需要不同團隊的成員來實現
2、當你在使用基礎類庫中的類時,你不想繼承這些類而只想添加一些方法時。
?
Category能實現上面的需求,當然也有使用Category是需要注意的問題:
1、Category可以訪問原始類的實例變量,但不能添加實例變量,如果想添加變量,那就通過繼承創建子類來實現。
2、Category可以重載原始類的方法,不大不推薦這么做,這樣會覆蓋掉原始類的方法。如果確實要重載,那就通過繼承創建子類來實現。
3、和普通接口有所區別的是,在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可以重載原始類的方法,但不推薦這么做,這么做的后果是你再也不能訪問原來的方法。如果確實要重載,正確的選擇是創建子類
- 名稱沖突,即當類別中的方法與原始類方法名稱沖突時,類別具有更高的優先級。類別方法將完全取代初始方法從而無法再使用初始方法。
總結
- 上一篇: HTML实现舔狗日记
- 下一篇: wincap的安装与环境配置