Objective-C :Category

來源:互聯網
上載者:User

標籤:

Category 引入

  在日常的開發中,可能會碰到這樣的需求:給某個類增加方法。比如說,需要給NSString類增加一個列印的方法。當然,我們可以建立一個類比如TestString,並繼承NSString類,在新的類TestString中實現 displayString方法。但是,這種方法有一個明顯的缺陷是:只有 TestString類有該方法,NSString類的其他子類,比如 NSMutableString 不能使用該方法。能否給 NSString 類增加一個方法,讓NSString以及NSString的所有子類都可以使用呢?答案可以的,Category可以完美的解決這個問題。

Category 的使用

  Objective-C 中使用Category的文法是使用 @interface關鍵字,和定義一個標準的類非常類似,不過不是使用冒號(:,:是繼承一個類時使用),而是使用 (),如下:

@interface NSString (PlayString)- (void)playString:(NSString *)content;@end

其中:括弧內的 PlayStirng 是Category的名稱。

  可以為任何一個類增加 Category,即使看不到這個類的原始碼。當為一個類增加Cateogry後,這個類以及這個類的所有子類都可以使用Category中的方法。在運行時,Category 中的方法和類中原來的代碼是沒有區別的。比如說,上例中,NSString 類增加Cateogry,Category中定義了 playString方法,該方法的實現如下:

- (void)playString:(NSString *)content{    NSLog(@"the content is %@",content);}

  這樣,NSString類的執行個體對象,以及NSString類的所有子類的執行個體對象,都可以使用 playString方法。如下:

NSString *myString = @"this is original NSString";[myString playString:myString];    NSMutableString *mutString = [[NSMutableString alloc] init];[mutString appendString:@"this is a subclass of NSString"];[mutString playString:mutString];

  除了給一個類增加方法外,Category 還有以下兩種使用情境:

    1:將一個大的、複雜的類檔案拆分成幾個小的類檔案。

    2:多個人開發同一個類檔案時,可以使用Category,分別開發自己的功能。

使用Category的注意事項  

  1:Category中方法的命名。

    (1):盡量不要和原始類中的方法重名,儘管這樣是合法的,但是和原始類中的方法重名絕對不是一個好的編程習慣。因為這樣造成的後果是,無論是原始類,還是原始類的子類,都無法使用原始類中的那個方法。通常來說,想要覆蓋父類中某個方法的情況,更適合用繼承來實現,而不是Category。

    (2):當一個原始類有多個 Category 時,各個Category 中的方法名要保持相異。儘管多個Category中方法名重複不會提醒錯誤,但是會發生一些莫名其妙的錯誤。多個Category中的方法名重複時,每個Category都會向原始類中增加一個函數,這樣在運行時,所調用的方法和我們所期望的可能會不一致。這種情況下,具體調用哪個Category中的方法和編譯器是相關的。

  2:Category中不能增加執行個體變數。雖然在Category中可以增加屬性,但是在 .m檔案中,編譯器不會自動合成執行個體變數,以及訪問執行個體變數的 getter/setter 方法。想要為某個原始類增加執行個體變數,這種情況可以用繼承來實現。

Category 原理初探

  實際上,Objective-C 中的類經過編譯後,在記憶體中都有一個方法列表,方法列表指向的是該方法的代碼塊地址。當向某個方法發送訊息時,就從方法列表中尋找方法。舉例來說有一個類 Person,該類經過編譯後產生的方法列表是: setName、getName、getSex ……。現在該類增加一個Category,Category中也實現了方法getName,則再次經過編譯後,產生的方法列表是: setName、getName(Category)、getName(原始類)、getSex ……,當給getName方法發送訊息時,從類的方法列表中尋找,找到第一個getName方法時,就不在繼續往下尋找,這樣使用的永遠是 Category中實現的 getName 方法。這也是為何要注意Category中方法命名的原因。

Objective-C :Category

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.