標籤:interface dynamic category number 命名方式
第十二章 類別
類別:
命名方式: 類名稱+類別名稱。
在Xcode中可以在建立檔案的類別中找到 Objective-C category表徵圖。
@interface部分
類別的聲明看起來非常像類的聲明:
@interface NSString (NumberConvenience)
-(NSNumber *) lengthAsNumber;
@end
括弧內(NumberConverience)叫做類別名,且它是添加給NSString類的。 整句話可以理解為:我們為NSString類添加了一個名為NumberConverience的類別。
可以在類別中添加屬性,但不能添加執行個體變數,而且屬性必須是@dynamic(動態)類型的,添加屬性的好處在於你可以通過點運算式來訪問setter和getter方法。
@implementation
@implementation NSString (NumberConvenience)
-(NSNumber *) lengthAsNumber{
NSUInteger length = [self length];
return ([NSNumber numberWithUnsignedInt:length]);
}
@end
類別的優勢:
3個用途:1.將類對實現代碼分散到多個不同的檔案或者架構中。
2.建立對私人方法的前向引用。
3.向對象添加非正式協議。(informal protocol)
類別的缺陷:
1.無法向類中添加新的執行個體變數,類別沒有空間容納執行個體變數。
2.名稱衝突,也就是類別中的方法與現有的方法重名。當發生衝突的時候,類別具有更高的優先順序。你的類別方法將會完全取代初始方法,導致初始方法不可用。
(使用全域字典來儲存物件與你想要關聯的額外變數之間的映射可以克服類別無法增加執行個體變數的局限。)
一個特殊的類別:類擴充。
特點:1.不需要名字。2.你可以在包含你的原始碼多類(也就是自己的類)中使用它。3.你可以添加執行個體變數。4.你可以將唯讀許可權改成可讀寫的許可權。5.建立數量不限。
@interface Things : NSObject
@property (assign) NSInteger thing1;
@property (readonly,assign ) NSInteger thing2;
-(void) resetAllValues;
@end
@interface Thing ()
{
NSInteger thing4;
}
@property (readwrite,assign) NSInteger thing2;
@property (assign) NSInteger thing3;
@end
這裡沒有繼承的父類,我們所做的基本上就是擷取Things類,並通過添加私人屬性和方法來擴充它。
常用的策略是將類別置於實現檔案多最前面。在訪問其他類的私人方法時,只要在類別中聲明這些方法編譯器就不會產生警告。
應用程式不可以訪問類裡面的私人變數和方法,否則將不能通過App Store。
非正式協議和委託類別
Cocoa中的類經常會有一種名為委託的技術,委託是一種對象,由另一個類請求執行某些工作。
run迴圈是一種Cocoa概念,它在等待某些事情發生之前一直處於阻塞狀態,既不執行任何代碼。除了監聽網路流量之外,run迴圈還處理像等待事件,(按鍵或按一下滑鼠)之類的操作。
#import <Foundation/Foundation.h>
@interface ITunesFinder : NSObject <NSNetServiceBrowserDelegate>
@end
再nsobject後使用了NSNetServiceBrowserDelegate協議 它告訴編譯器和其他對象,該類符合這個名稱點協議並實現了其方法。
委派物件只需要實現已經打算調用的方法即可。
託管強調類別的另一種應用:被發送給託管對象的方法可以聲明為一個NSObject的類別。
650) this.width=650;" title="螢幕快照 2015-07-24 下午10.00.33.png" alt="螢幕快照 2015-07-24 下午10.00.33.png" src="/e/u261/themes/default/images/spacer.gif" class="ynote-attachment" style="background:url("/e/u261/lang/zh-cn/images/localimage.png") no-repeat center;border:1px solid #ddd;" />
NSNetServiceBrowser的實現可以將這些訊息之一發送給任何對象,無論這些對象實際上屬於哪個類,這也意味著只要實現了委託方法,任何類的對象都可以成為委派物件。
建立一個NSObject類別稱為建立一個非正式的協議。非正式協議只是一種運算式,他表示“這裡有一些你可能希望實現的方法,你可以使用它們更好的完成工作。”
選擇(selector)器只是一個方法的名稱,但他以OC運行時使用特殊方式編碼,以快速執行查詢。
NSObject提供了一個名為respondsToSelector:的方法,該方法用來詢問對象以確定其是否能夠響應某個特定點訊息。
Car *car = [[Car alloc] init];
if ([car respondsToSelector:@selector(setEngine:)]) {
NSLog(@"yo yo ..");
}
這段代碼可以正常輸出yo yo .. ,因為Car類的對象確實能夠響應setEngine:訊息。
為了確認託管對象能否響應訊息,NSNetServiceBrowser將調用respondsToSelector:@selector(netServiceBrowser:didFindService:moreComing:)。如果該託管對象能夠響應給定的訊息,則瀏覽器向該對象發送此訊息。否則瀏覽器將暫時忽略託管對象,繼續正常運行。
選取器可以被傳遞,可以用作方法的參數使用,甚至可以作為執行個體變數被儲存。
Foundation架構中的NSTimer就是這樣的類,它能夠反覆大向一個對象發送訊息。
本章總結:
類別的概念,功能。類擴充,選取器。
這一章看起來比較容易理解,但是卻不清楚該怎麼用。。```
第十三章 協議
正式協議:
包含了方法和屬性的有名稱列表,但與非正式協議不同的是正式協議要求顯式的採用。方法是在類的@interface聲明中列出協議的名稱。採用協議就意味著你承諾實現該協議所有方法。否則將得到警告。
通常可以將NSObject作為根協議,但是與NSObject類不同,NSObject類符合NSObject協議,這意味著所有對象都符合NSObject協議。
id類型表示一個可以指向任何類型的對象的指標,它是一個泛型物件類型。你可以講任何對象複製給一個id類型的變數,反之亦可。
NSControl類中有一個名為setObjectValue:的方法,該方法要求對象追求NSCopying協議: -(void) setObjectValue: (id<NSCopying>) object;
在協議中如果增加了兩個協議修飾符: @optional 和 @required 。在這兩個修飾符之間的方法可以選擇性的實現。
委託(delegation)方法:
委託就是某個對象指定另一個對象處理某些特定的設計模式。
-(id <NSNetServiceBrowserDelegate>) delegate;
-(void) setDelegate:(id <NSNetServiceBrowserDelegate>) delegate;
第一個方法會返回當前的委派物件(如果沒有則返回nil),第二個是用來設定委託的,參數的委託類型告訴我們,只要遵守所需的協議,就可以設定任意對象為委託。
objective-C 類別/協議。