標籤:objective-c ios-開發 ios 類別 類
12.1 建立類別
類別(category)是一種為現有的類添加新方法的方式
例:擷取字串的長度並存入NSDictionary字典中
NSNumber *number; number = [NSNumber numberWithUnsignedInt: [string length]]; // ... do something with number
@interface NSString (NumberConvenience)- (NSNumber *) lengthAsNumber; @end // NumberConvenience
注意:
- 括弧內寫入類別的名稱,添加給NSString的
- 類別不能添加執行個體變數,所以沒有執行個體變數的聲明部分
可以添加屬性,但屬性必須是dynamic
類型的,添加屬性的好處是可以通過點運算式訪問setter和getter方法
- (NSNumber *) lengthAsNumber{ unsigned int length = [self length]; return ([NSNumber numberWithUnsignedInt: length]); //向字串發送lengthAsNumber,返回該字串的長度的NSNumber對象} // lengthAsNumber
測試檔案:
NSMutableDictionary *dict; dict = [NSMutableDictionary dictionary]; [dict setObject: [@"hello" lengthAsNumber] forKey: @"hello"]; [dict setObject: [@"iLikeFish" lengthAsNumber] forKey: @"iLikeFish"]; [dict setObject: [@"Once upon a time" lengthAsNumber] forKey: @"Once upon a time"]; NSLog (@"%@", dict); //輸出:“鍵=鍵內容”
優點:只要輸入一個字串,向該字串發送lengthAsNumber,立即能返回該字串的長度的NSNumber對象
注意:
此類別屬於NSString,因此任何NSString對象都能響應lengthAsNumber訊息
12.11 類別的缺陷:
- 無法向類中添加新的執行個體變數
- 名稱衝突,類別的方法名與現有的方法重名時,類別具有更高的優先順序(利用首碼避免)
12.12 類別的優勢:
- 將類的實現代碼分散到多個不同檔案或架構中
- 建立對私人方法對向前引用
- 向對象添加非正式協議(informal protocol)
12.2 類擴充(class extension)
類擴充:一種特殊的類別,不需要名字。
特點:
- 不需要名字
- 可以在你自己的類中使用它
- 可以添加執行個體變數
- 可以將唯讀許可權改成可讀寫的許可權
- 建立數量不限
例:建立Things類的擴充
@interface Things : NSObject@property (assign) NSInteger thing1;@property (readonly, assign) NSInteger thign2;
//擷取Things類,並通過添加私人屬性和方法擴充它@interface Things(){ NSInteger thing4;//私人的}@property (readwrite, assign) NSInteger thing2;//改變了讀寫權限,只能在這個類中訪問的私人方法,在公用的介面只有getter方法@property (assign) NSInteger thign3;//私人的
注意:
物件導向編程的一個特徵就是資訊隱藏,只需要把使用者需要的展示出來,其他的不需要。我們可以把這個類別放在.m檔案中,也可以放在私人的標頭檔中。
12.3 利用類別分散實現代碼
如果想將大型(有很多方法)的類分散到多個不同的.m檔案中,可以使用類別。
NSWindow類有數百個方法,但使用分類:
@interface NSWindow(NSKeyboardUI) //鍵盤@interface NSWindow(NSToolbarSupport) //工具列@interface NSWindow(NSDrag) //拖放功能@interface NSWindow(NSCarbonExtensions)
注意:
- 類別可以訪問其繼承的類的執行個體變數
- 不僅可以將一個類的實現代碼分散到多個不同的源檔案中,還可以分散多個不同的架構中
Cocoa的設計人員通過類別使資料功能放在Foundation架構中,而繪圖共呢個放在Appkit架構中。
12.4 通過類別建立向前引用(Forward References)
如果在不方便將方法聲明的前提下調用方法,或者正在使用的是另一個類中尚未發布的方法,那麼就需要類別。
具體做法:
Car類的公用介面裡聲明rotateTires
的方法,在類別中聲明move
TireFromPosition:toPosition:
的方法來實現rotateTires
的方法,rotateTires方法可以使用它。
@intreface Car(Private)-(void)moveTireFromPosition:(int) pos1 toPosition: (int) pos2;@end // Private
注意:放入各自的@implementation檔案中
12.5 非正式協議和委託類別
非正式協議是NSObject的一個類別,列出了對象可以響應的方法。非正式協議用於實現委託
委託(delegate)是一種對象,由另一個類請求執行某些工作。委託是一種允許你輕鬆定製對下崗行為的技術。
例:
當使用者點擊某行時,tableView對象準備執行之前,它會詢問其委派物件是否能選擇此行。
12.51 ITUnesFinder 項目 (略)
//新的NSNetServiceBrowser對象: NSNetServiceBrowser *browser; browser = [[NSNetServiceBrowser alloc] init]; //新的ITunesFinder對象 ITunesFinder *finder; finder = [[ITunesFinder alloc] init]; //告訴 net browser將 ITunesFinder 對象作為代理 [browser setDelegate: finder]; //告訴瀏覽器搜尋iTunes共用 [browser searchForServicesOfType: @"_daap._tcp" inDomain: @"local."];
12.52 委託和類別
委託是類別的另一種應用,一個NSObject的類別可以被發送給委派物件
@interface NSObject (NSNetServiceBrowserDelegateMethods)- (void) netServiceBrowserWillSearch: (NSNetServiceBrowser *) browser;- (void) netServiceBrowserDidStopSearch: (NSNetServiceBrowser *) browser;- (void) netServiceBrowser: (NSNetServiceBrowser *) browser didRemoveService: (NSNetService *) service moreComing: (BOOL) moreComing;@end
通過聲明為NSObject的類別,NSNetServiceBrowser可以給任何對象(作為代理的對象)發送其中一條訊息-為非正式協議
注意:對於非正式協議,你只聲明你想聲明的即可。
12.53 響應選取器
選取器(selector):只是一個方法名稱
指定選取器:@selector()
;
Car類的setEngine:
方法的選取器:@selector(setEngine:)
Car類的setTire:atIndex:
方法的選器:@selector(setTire:atIndex:)
詢問對象其是否能響應某個特定的訊息
Car *car = [[Car alloc] init];if([Car respondsToSelector: @selector(setEngine:)]){ NSLog(@"Yes");}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
[學習筆記—Objective-C]《Objective-C-基礎教程 第2版》第十二章 類別