2011-10-03 65 views
3

這可能是一個天真的問題,但我感覺有點失落。我在Apple Documentation閱讀iOS開發人員指南,但沒有太大意義。讓我以儘可能最短的方式解釋我的困境。ID確認一個協議,但在哪裏將實施?

可以說我有如下協議,

@protocol MyProtocol<NSObject> 
- (void)someMessage; 
@end 

,比我的代碼我聲明這樣的變量,

id<MyProtocol> someVar; 

到目前爲止好,但someVar是一個id類型那麼我們將在哪裏實施-(void) someMessage;


注:我有知識,諸如接口的定義 功能的實現應該是其實現了 界面一類的內部。這種理解來自Java,因此在Java中,知道哪個對象來自哪個類以及該類實現哪個接口 是顯而易見的。但是,上述目標C方式只是讓我感到困惑:(。


+0

協議是您在Java中稱爲'接口'的協議:)對於其餘部分,Mark提供了正確的答案。 – Phlibbo

回答

6

一個協議當你寫:

id<MyProtocol> someVar 

你只是指出「someVar」將是任何類的對象,但該類會尊重協議MyProtocol。

所以你的代碼中會有一些點將實例化一些變量。此時,某些變量將被關聯到一個類。該類必須滿足MyObject協議。 請注意,編譯器會盡力在出現問題時提醒您,例如如果您將此對象投射到某個不尊重協議的類,例如假設你的協議定義了一個名爲「protocolMethod」,則方法:

[(NSArray *)someVar protocolMethod] 

將生成編譯器警告(「NSArray的可能不響應protocolMethod」)。

當然,你永遠不會受到運行時錯誤的保護:所以如果在運行時你創建了一些不符合協議的類,那麼任何對協議方法的調用都會引發異常。

+0

你應該使用Markdown格式化你的文章,否則類似代碼片段的東西可能顯示不正確。 http://stackoverflow.com/editing-help – BoltClock

4

你需要實現一個實現協議的方法的類 如

@interface MyObject: NSObject <NyProtocol> 
- (void)someMessage; 
@end 

@implementation MyObject 
-(void)someMessage() 
{ 
    printf(@"a message"); ... 
} 
@end 

然後用這個作爲

someVar = [MyObiect alloc]...... 

您也可以將該方法作爲NSObject的類別實現,以便所有類都可用。

見採用從蘋果Objective C concept document

4

Objective-C協議在概念和代碼方面與Java接口鬆散地相似,簡單起見。

如果將Java變量聲明爲接口類型,則表示它可以接受任何實現該接口的對象。在Objective-C中,id變量表示任何指針類型,所以id<MyProtocol>意味着指向採用MyProtocol的對象的任何指針,並且在此意義上類似於Java接口類型聲明。

在Java中,您在類中實現接口方法,並聲明該類來實現接口。同樣的,在Objective-C中,你需要在一個類中實現一個協議方法,並讓該類採用該協議。

這裏的Java和Objective-C之間的代碼比較(同樣它的兩個相似的概念,只是一個鬆散的比較):

的Java

public interface MyInterface { 
    void someMethod(); 
} 

public class MyClass implements MyInterface { 
    public void someMethod() { 
     System.out.println("Some method was called"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     // Any class that implements MyInterface can be 
     // assigned to this variable 
     MyInterface someVar = new MyClass(); 
     someVar.someMethod(); 
    } 
} 

Objective-C的

@protocol MyProtocol <NSObject> 
- (void)someMessage; 
@end 

@interface MyClass : NSObject <MyProtocol> 
- (void)someMessage; 
@end 

@implementation MyClass 

- (void)someMessage { 
    NSLog(@"Some message was sent"); 
} 

@end 

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

    // Any class that adopts MyProtocol can be 
    // assigned to this variable 
    id<MyProtocol> someVar = [[MyClass alloc] init]; 
    [someVar someMessage]; 

    [someVar release]; 
    [pool drain]; 
    return 0; 
} 
+0

這確實是一個很好的解釋+1 :),但是通過接受viggio24的回答給予信任,因爲他/她的回答讓我第一次理解哈哈。謝謝 – doNotCheckMyBlog

0

I wrote a category on NSObject - called StrictProtocols - that solves this "problem".它實現了以下方法...

/* "non" doesn't implement ANY of the declared methods! */ 
[non implementsProtocol:proto];   -> NO; 
[non implementsFullProtocol:proto];  -> NO; 

/* "semi" doesn't implement the @optional methods */ 
[semi implementsProtocol:proto];  -> YES; 
[semi implementsFullProtocol:proto]; -> NO; 

/* "strict" implements ALL, ie the @optional, @required, and the "unspecified" methods */ 
[strict implementsProtocol:proto];  -> YES; 
[strict implementsFullProtocol:proto]; -> YES;