Objective-C類別(catagory)

在編寫面向對象的程序時,你經常希望向現有的類添加一些新的行爲:你總是能夠爲對象提供使用這些新方法的新手段。當希望爲現有的類增加新行爲時,我們通常會創建子類,但是有時候子類並不方便。例如,你可能會希望爲NSString類增加一些新行爲,但是你知道NSString實際上只是一個類簇的前臺表示,因而無法爲這樣的類創建子類。在其他情況下,你也許可以創建子類但你使用的卻是工具包或類庫,因爲又無法處理新類的對象。例如,當使用類方法stringWithFormatFor生成一個新的字符串時,你新建的NSString類的子類無法返回。

利用Objective-C的動態運行時分配機制,可以爲現有的類添加新方法,這種爲現有的類添加新方法的方式稱爲類別catagory,他可以爲任何類添加新的方法,包括那些沒有源代碼的類。類別使得無需創建對象類的子類就能完成同樣的工作。


一、創建類別
1、聲明類別
聲明類別與聲明類的形式很相似

@interface  NSString(NumberConvenience)   //NumberConvenience爲NSString的一個類別
-(NSNumber *)lengthAsNumber;
@end//NumberConvenience
這個聲明有兩個特點:
     (1)現有的類位於@interface關鍵字之後,其後是位於圓括號中的類別名稱。類別名稱是NumberConvenience,而且該類別將向NSString類中添加方法。換句話說:“我們向NSString類中添加一個名稱爲NumberConvenience的類別。”
        同名類別有唯一性,但是可以添加任意多的不同名類別。
     (2)可以執行希望向其添加類別的類以及類別的名稱,還可以列出添加的方法
        不可以添加新的實例變量,類別生命中沒有實例變量部分。

2、實現類別
    @implementation NSString(NumberConvenience)
    -(NSNumber *)lengthAsNumber
    {
        unsigned int length = [self length];
        return ([NSNumber numberWithUnsignedInt : length]);
    }  //lengthAsNumber
    @end   //NumberConvenience
在實現部分也包括類名、類別名和新方法的實現代碼

3、類別的侷限性
有兩方面侷限性:
    (1)無法向類中添加新的實例變量,類別沒有位置容納實例變量。
       (2)名稱衝突,即當類別中的方法與原始類方法名稱衝突時,類別具有更高的優先級。類別方法將完全取代初始方法從而無法再使用初始方法。
無法添加實例變量的侷限可以使用字典對象解決

4、類別的作用
類別主要有3個作用:
       (1)將類的實現分散到多個不同文件或多個不同框架中。
       (2)創建對私有方法的前向引用。
       (3)向對象添加非正式協議。



二、功能一、利用類別分散實現
我們可以將類的接口放入頭文件中,從而將類的實現放入.m文件中
但不可以將@implementation分散到多個不同的.m文件中,使用類別可以完成這一工作
利用類別,可以將一個類的方法組織到不同的邏輯分組中,使編程人員更加容易的閱讀頭文件
舉例代碼:
頭文件CatagoryThing.h包含類的聲明和一些類別,導入Foundation框架,然後帶有3個整型變量的聲明

#import<Foundation/Foundation.h>
@interface CategoryThing : NSObject {
   int thing1;
   int thing2;
   int thing3;
}
@end // CategoryThing
類聲明之後是3個類別,每個類別具有一個實例變量的訪問器,將這些實現分散到不同的文件中
@interface CategoryThing(Thing1)
- (void) setThing1: (int) thing1;
- (int) thing1;
@end // CategoryThing (Thing1)

@interface CategoryThing (Thing2)
- (void) setThing2: (int) thing2;
- (int) thing2;
@end // CategoryThing (Thing2)

@interface CategoryThing (Thing3)
- (void) setThing3: (int) thing3;
- (int) thing3;
@end // CategoryThing (Thing3)

類別可以訪問其繼承的類的實例變量,類別的方法具有最高的優先級
類別可以分散到不同文件中,甚至不同框架中



三、功能二、使用類別創建前向引用
前面提到,Cocoa沒有任何真正的私有方法。只要知道對象支持的某個方法的名稱,即使該對象所在類的接口中沒有該方法的聲明,你也可以調用該方法。

不過,如果你這樣使用,編譯器會報警告。如果這時候,你使用可類別,就可以消除這些警告了。

例子,有這麼一個類MethodsTest

接口聲明瞭兩個方法  showInfo1()和showInfo2()


在實現中,有3個方法


也就是說showInfo3()方法
在接口中沒有聲明,如果直接使用會報出警告

如果,加上類別,就不會有警告了。//類別名爲空的 類別


四、功能三、向對象添加非正式協議

創建一個NSObject的類別稱爲“創建一個非正式協議”。因爲,NSObject是頂級父類,在NSObject中添加了該方法,也就是說通過繼承關係,所有的類中都有該方法。

正式協議是通過protocol指定的一些列方法的聲明,然後由實現該協議的類自己去實現這些方法。而非正式協議是通過向NSObject中添加一個類別來實現,然後子類去繼承NSObject。其實都差不多。

不過,非正式協議已經漸漸被正式協議取代,正式協議最大的優點就是可以使用泛型約束,而非正式協議則不可以。

(原文:http://blog.csdn.net/lonelyroamer/article/details/7704896)

發佈了16 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章