2010-11-19 86 views
2

在我的項目中我有3個類,我們稱它們爲Apple,Orange和Pear。XCode不正確的警告「沒有實現X協議」

蘋果和橙都有代表屬性。
它們都在頭文件中定義了名爲AppleDelegate和OrangeDelegate的協議。
他們每個人都有類似簽名的初始化:

- (id)initWithDelegate:(id<AppleDelegate>)delegate 
- (id)initWithDelegate:(id<OrangeDelegate>)delegate 

梨實現OrangeDelegate和定義如下:

@interface Pear : NSObject <OrangeDelegate> 

裏面梨,我做這樣的判斷:

Orange *anOrange = [[[Orange alloc] initWithDelegate:self] autorelease]; 

的結果在此編譯器中警告:

Class 'Pear' does not implement the 'AppleDelegate' protocol 

在我看來,編譯器不能識別初始化器中的協議。換句話說,它只能識別此簽名兩種:

- (id)initWithDelegate:(id)delegate 

因爲當我點擊在梨初始化「跳轉到」,它帶來了兩個類的選項。

除了重命名我的方法之外,是否有任何方法可以更正此警告?

+0

多數民衆贊成在奇怪,你永遠不會分配梨是一個蘋果代表,東西必須在你的defenitions我認爲 – Daniel 2010-11-19 01:16:41

+0

@丹尼爾 - 這是我的想法,但我肯定它不是。我剛添加蘋果,並出現警告。在此之前,Orange和Pear都存在,並且沒有任何警告地編譯。當我加入蘋果時,Orange或Pear都沒有被修改,但突然他們開始發出警告。 – DougW 2010-11-19 01:19:53

回答

3

問題是'alloc'是一個從NSObject繼承的方法,定義爲返回類型'id'。所以如下:

[Orange alloc] 

計算一個'id'類型的對象。當你在那個對象上調用initWithDelegate時,編譯器不知道類型,並在這種情況下猜測錯誤的類型。所以你可以用下面的命令來消除這個警告:基本上,這是因爲構造函數不是Objective-C中的語言級功能,而僅僅是一個約定。

編輯:見下文;我想另一個解決辦法是補充:

+ (Orange *)alloc; 

橙色,這沒有什麼更復雜得多:

+ (Orange *)alloc 
{ 
    return [super alloc]; 
} 

我想這部分是一個設計決策 - 應課負責明知其構造函數方法可能與其他類的名稱衝突,或者應該使用相同構造函數導入多個類定義的文件負責消除歧義。雖然簡單的語法看起來可能更加緊湊。

+0

啊,是的,這是有道理的。我發現將自我投射到(id)也消除了警告。任何一個都有點蹩腳和醜陋,但看起來像是或重命名初始化器。謝謝。 – DougW 2010-11-19 02:02:03

+0

考慮了一會兒之後(我從來沒有在這個問題上看到任何適當的建議,我只是從第一原理開始回答),我想你也可以重寫init,而不是隻允許它從NSObject繼承。我已經將其編輯到我的答案中,因爲使用源代碼很容易。 – Tommy 2010-11-19 02:10:33

相關問題