2010-01-05 28 views
50

我想知道是否有人可以解釋目標C中的非正式協議?我嘗試在蘋果文檔和其他一些書上理解它,但我的頭仍在旋轉,所以如果有人可以用例子來解釋,我將非常感激。非正式協議在Objective-C?

謝謝。

回答

58

非正式協議是,作爲Jonnathan說,通常宣佈的NSObject沒有實現相應的類別(最常見的 - 有這並提供NSObject的虛擬實現罕見的一個)。

從10.6開始(在iPhone SDK中),這種模式不再使用。具體來說,什麼被宣佈爲10.5(和之前)如下:

@interface NSObject(NSApplicationNotifications) 
- (void)applicationWillFinishLaunching:(NSNotification *)notification; 
... 
@interface NSObject(NSApplicationDelegate) 
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 
... 

現聲明如下:

@protocol NSApplicationDelegate <NSObject> 
@optional 
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; 
... 
- (void)applicationWillFinishLaunching:(NSNotification *)notification; 
... 

也就是說,非正式的協議,現正與一幫@optional方法聲明爲@protocol小號。

在任何情況下,非正式協議都是方法聲明的集合,您可以選擇實現方法來更改行爲。通常(但並非總是),方法實現在委託的上下文中提供(例如,表視圖的數據源必須實現一些必需的方法,並可以選擇實現一些其他方法)。

4

所有非正式協議都是某類(通常爲NSObject)上的一個類別,它聲明瞭該協議的接口。 AppKit爲其代表團使用了很多。

您編寫的子類可以實現這些方法。這與正式協議的區別在於正式協議使用@protocol ... @end表示法進行聲明。沒有檢查類是否實現了給定的非正式協議。

我幾乎總是使用正式的協議,但我想如果你想提供默認行爲(只需提供一個可以被覆蓋的類別的實現),非正式協議就很有用。

+0

那麼它關於「子類」的東西,然後執行它們?我正在嘗試語法。 – itsaboutcode 2010-01-06 00:22:07

9

給出非正式協議的常見示例之一是定義回調函數。假設你正在使用一個庫,可以讓你在後臺下載一些東西。這個庫允許你註冊一個完成時被調用的回調對象。

- (void)download:(NSURL*)url whenComplete:(id)callback 

當下載完成後,它會調用你的回調對象的具體方法:

- (void)downloadComplete:(NSURL*)url 

當然,也不能保證你的回調對象實際上實現了這個方法。非正式協議使用一個類別在NSObject上提供這些方法的簡單實現。因此,系統中的所有對象都將響應downloadComplete:方法,儘管默認情況下它們不會響應該方法。覆蓋downloadComplete:方法的類可以提供更多有用的功能。

到目前爲止,您可以使用正式的協議完成同樣的事情。但是,非正式協議允許您使用可選的方法。實現正式協議的類必須爲協議中的每個方法提供實現。實現非正式協議的類可以省略任何方法的實現 - 它已經繼承了NSObject的實現。由於Objective-C 2.0,正式的協議可以包含可選的方法。另外,Apple可能正在從新API的非正式協議中移除 - UIAccelerometerDelegate是一個正式協議。

+0

這裏使用術語'callback'在這裏可能會引起混淆,特別是在存在塊的世界。你在談論的是代表團。 (我意識到這個答案在2010年可能更有意義。) – 2014-11-21 20:07:24

3

基於「喬納森斯特林」的答案,我可以說下面的代碼代表非正式的協議?

蘋果文檔:

「當用於聲明的協議,一類接口沒有一個對應的實現取而代之的是,實施該協議在自己的接口文件再次聲明方法的類,並沿定義它們。在其實施文件中使用其他方法。「

#import <Foundation/Foundation.h> 

@interface Cat1 : NSObject { 


} 
- (void) simpleMethod; 

@end 

@implementation Cat1 

- (void) simpleMethod 
{ 

    NSLog(@"Simple Method"); 
} 

@end 


@interface Cat1 (Cat2) 
- (void) addingMoreMethods; 

@end 




@interface MYClass : Cat1 

@end 

@implementation MYClass 

- (void) addingMoreMethods 
{ 
    NSLog(@"Testing!"); 
} 
@end 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 


    MYClass *myclass = [[MYClass alloc] init]; 
    [myclass addingMoreMethods]; 
    [myclass release]; 
    [pool drain]; 
    return 0; 
} 
+0

Sorta。 * Cat2 *中聲明的方法是一個非正式的協議,或多或少。但是,這個用法不是 - 通常,你會看到if([myclassresponseToSelector:@selector(addingMoreMethods)])[myclass addingMoreMethods];'。 – bbum 2010-01-06 00:31:11

+0

感謝bbum,如果使用太多,我不感興趣,但我真的很想理解整個概念! – itsaboutcode 2010-01-06 00:35:07

+3

然而,關鍵是非正式協議是由可以選擇實現的方法組成的。因此,呼叫站點*必須*檢查它是否被實現,否則呼叫會崩潰! – bbum 2010-01-06 00:46:40

1

一個非正式協議定義了對象必須理解哪些方法。這被稱爲「符合協議」。符合協議與類層次結構無關。 當聲明一個指針來保存對一個對象的引用時,你可以定義這個對象應符合哪些協議。如果您編寫的代碼指定的對象不符合所有必需的協議,您將在編譯時收到警告。 非正式協議可幫助您依賴對象理解的一組方法。您不必在代碼中調用isKindOfClass:或respondsTo:來檢查傳入的對象是否適合您的處理。協議是一種面向方面的編程。

5

我們通過在一個類別聲明分組的方法定義了一個informal protocol

@interface NSObject (MyXMLSupport) 
- initFromXMLRepresentation:(NSXMLElement *)XMLElement; 
- (NSXMLElement *)XMLRepresentation; 
@end 

Informal protocol s的通常聲明爲NSObject類的類,由於其廣泛地與從繼承的任何類關聯 方法名NSObject

因爲所有類都繼承自根類 ,所以這些方法並不侷限於繼承層次結構的任何部分。 (也可以將 和informal protocol聲明爲另一個類的類別,以將其限制爲繼承層次的某個分支,但是沒有理由這樣做)。

當用於聲明協議時,類別接口沒有相應的實現。相反,實現該協議的類會在其自己的接口文件中再次聲明方法,並在其實現文件中將其與其他方法一起定義爲 。

5

非正式協議是由類的手段來添加可選方法的一個對象一個方式。

所以一個疑問可能出現

它是會成爲非正式的協議,如果有對協議本身的任何可選的方法呢?

答案是否定的。

如果方法在協議中聲明,它被認爲是符合一類沒有類的任何使用那麼它的正式協議

注:在協議

可選方法在目標C 2.0被引入,從而在這之前的目的是通過類的裝置通過非正式協議即實現。

類別:

它意味着要替代的子分級又名繼承語言水平的功能。

我希望它在這個上流下一些石灰燈..

+1

感謝那個''注意:''給了我完整的圖片:-) – byJeevan 2016-04-27 03:41:27