objective-c的categories(分類)

來源:互聯網
上載者:User

objective-c的categories(分類)
 一,當你想要為某個class 新增methods,你通常會擴充(extend,即繼承)它。然而這不一定是個完美解法,特別是你想要重寫一個class 的

某個功能,但你卻沒有原始碼時。Categories 允許你在現有的class 加入新功能,但不需要擴充它。Ruby 語言也有類似的功能。

例子一:
1,MyObjectCateName.h:

#import <Foundation/NSObject.h>#import "MyObject.h"  //該標頭檔已經定義了MyObject類//重點是這行:MyObject是已經存在的類,()裡面是分類的名字,該分類擴充了之前MyObject的方法add和sub@interface MyObject(MyObjectCateName)-(MyObject*) add: (MyObject*) m;-(MyObject*) sub: (MyObject*) m;@end

2,MyObjectCateName.m:

#import "MyObjectCateName.h" //重點是這行:MyObject是已經存在的類,()裡面是分類的名字,該分類擴充了之前MyObject的方法add和sub@implementation MyObject(MyObjectCateName)-(MyObject*) add: (MyObject*) m {     return [[MyObject alloc] initWithNumerator: numerator + [m numerator]];}-(MyObject*) sub: (MyObject*) m {     return [[MyObject alloc] initWithNumerator: numerator - [m numerator]];}@end

二,(同一個class)只能有一個同名的category,其他的categories 得加上不同的、獨一無二的名字,Categories 在建立private methods 時十分有用。因為Objective-C

並沒有像Java 這種private/protected/public methods 的概念,所以必須要使用categories 來達成這種功能。作法是把private method 從你的class header (.h) 檔案移到implementation (.m) 檔案。

例子2:

1,MyClass.h

#import <Foundation/NSObject.h>@interface MyClass: NSObject-(void) publicMethod;@end

2,MyClass.m

#import <stdio.h>#import "MyClass.h"@implementation MyClass-(void) publicMethod {printf( "public method\n" );}@end// private methods@interface MyClass (Private)-(void) privateMethod;@end@implementation MyClass (Private)-(void) privateMethod {printf( "private method\n" );}@end

三,如何使用Categories
對於在Objective-C中Categories的使用,有以下幾種情況:
1)擴充已有的類

      舉個例子,你可以向Cocoa架構中定義好的類中增加新的方法。新增的方法同時也會被子類繼承,在運行時將無法區分這些方法是新增的還是原來類已經定義好的。

2)作為子類的替代方案

      除了通過定一個子類來擴充已有的類,你也可以通過Category直接向已有的類增加新的方法來實現。舉例來說,你可以向NSArray和其它Cocoa類增加新的Categories來擴充已有的類。如同定義子類,你同樣也不需要知道被擴充類的原始碼。

3)通過使用多個代碼檔案來定義一個類
     舉個例子,你可以將一個規模比較大的類所有方法進行分組,然後將每組方法放到一個Category中,每個Category則用一個檔案來定義。在開發過程中,這樣的好處是顯而易見的。

    提供一個簡單的方法對相關的方法進行分組。不同的類中相似的方法可以統一放到相同的檔案中,如果有多個開發人員需要同時實現一個類,通過將類的方法分成不同的Categories可以簡化代碼管理 ,可以對一個規模非常大的類進行增量編譯,減少重複編譯的時間 ,可以將常用方法集中在一起,便於尋找和參考 ,如果同一個類針對不同的應用有不同的實現,可以將不同的部分分別放入一個單獨的檔案中,以便代碼的維護 。

4)可以申明非正式的協議(protocols)
    儘管Objective-C能夠允許使用Category覆蓋重寫類方法,甚至是定義在類介面中的方法,但強烈不建議這種用法。

Category不能完全代替子類,有以下幾個最大的缺點:
       當在Category中覆蓋一個繼承的方法,在Category中的方法可以通過向super類發送一個訊息來調用被繼承的方法。但是,如果Category中覆蓋的那個方法已經在這個類的其它Category定義過了,則之前定義的方法將沒有機會被程式調用 ,在Category中無法確定其能夠可靠的覆蓋某個方法,而這個方法已經在其它的Category中定義過。這個問題在使用Cocoa架構時尤其突出。當你想覆蓋某個架構已經定義好的方法時,該方法已經在其它Category中實現,這樣就無法確定哪個定義和實現會被最先使用,帶來很大的不確定性。 
      如果你重新覆蓋定義了一些方法,往往會導致這個方法在整個架構中實現發生了變化。舉例來說,如果你增加了NSObject中windowWillClose:的實現,
這會導致所有的視窗調用那個新實現的方法,從而改變所有NSWindows執行個體的行為。這會帶來很多不確定性,並很有可能導致程式的崩潰。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.