2011-11-12 99 views
40

我試圖編譯,但每次我做,一個方法會拋出一個奇怪的「預期類型」錯誤。我在頭文件中有一個方法:「預期類型」錯誤指向方法的返回類型

-(ANObject *)generateSomethingForSomethingElse:(NSString *)somethingElse; 

該方法返回類型的錯誤點。我已經使用#import "ANObject.h"ANObjectANObject導入標題中。

爲什麼會發生這種情況?

+0

似乎很好..你可以發佈你的代碼的一部分? – Devarshi

+0

也...是其他框架的ANObject部分? – Devarshi

+4

請編輯您的問題以包含ANObject.h的內容和提供您問題的標題。並且請顯示您的實際代碼,而不是可能不包含問題的組成代碼。 –

回答

89

這是做的順序的源文件編譯您已經大概知道,你不能調用定義之前的方法(見下面的僞代碼):

var value = someMethod(); 

function someMethod() 
{ 
    ... 
} 

這會導致編譯時錯誤,因爲someMethod()尚未定義。類也是如此。類由編譯器依次編譯。

所以,如果你想象所有的類在編譯之前被放入一個巨大的文件中,你可能已經能夠看到這個問題。讓我們來看看ShipBoatYard類:

@interface BoatYard : NSObject 
@property (nonatomic, retain) Ship* currentShip; 
@end 

@interface Ship : NSObject 
@property (nonatomic, retain) NSString* name; 
@property (nonatomic, assign) float weight; 
@end 

再次,因爲Ship類尚未定義,我們不能引用它。解決這個問題非常簡單,改變編譯順序並編譯。我敢肯定,你familliar與此屏幕的XCode:

但你知道,你最多可以在列表中上下拖動文件?這改變了文件將被編譯的順序。因此,只需將Ship類移動到BoatYard類以上,並且一切都很好。

但是,如果您不想這麼做,或者更重要的是,如果兩個對象之間存在循環關係會怎麼樣呢?讓我們通過將參考目前BoatYardShip是增加該對象圖的複雜性:

@interface BoatYard : NSObject 
@property (nonatomic, retain) Ship* currentShip; 
@end 

@interface Ship : NSObject 
@property (nonatomic, retain) BoatYard* currentBoatYard; 
@property (nonatomic, retain) NSString* name; 
@property (nonatomic, assign) float weight; 
@end 

哦,親愛的,我們現在有一個問題。這兩個不能並行編譯。我們需要一種方法告知編譯器Ship *類真的存在。這就是爲什麼@class關鍵字非常方便。要說得通俗一點,你說的是:「相信我,Ship確實存在,你很快就會看到它。」爲了把它放在一起:

@class Ship; 

@interface BoatYard : NSObject 
@property (nonatomic, retain) Ship* currentShip; 
@end 

@interface Ship : NSObject 
@property (nonatomic, retain) BoatYard* currentBoatYard; 
@property (nonatomic, retain) NSString* name; 
@property (nonatomic, assign) float weight; 
@end 

現在編譯器知道,因爲它編譯BoatYard,一個Ship類定義將很快出現。當然,如果沒有,彙編仍然會成功。

但是,所有@class關鍵字都會通知編譯器該類很快就會出現。它是不是代替#import。你還必須導入頭文件,否則你不會有任何類的內部訪問:

@class Ship 

-(void) example 
{ 
    Ship* newShip = [[Ship alloc] init]; 
} 

這可不行,而且會失敗,錯誤消息說,船舶是一個向前聲明。一旦你#import "Ship.h",那麼你將能夠創建對象的實例。

+0

史蒂夫,你能解釋爲什麼會發生這種情況嗎?歡呼聲 – theiOSDude

+2

@ burrows111:經過反思,這是一個非常懶惰的答案;我寫這本書時一定很匆忙。其他答案解釋瞭如何解決它,但我看不到解釋它爲什麼會發生的解釋。我希望編輯的答案可以幫助你。 –

+0

使更多的意義!歡呼夥計! – theiOSDude

1

通常當我看到這樣的錯誤時,是因爲我在上一行有一個錯字,比如一個額外的或缺少的括號或其他東西。 。

52

我發現這個錯誤發生在頭部有循環依賴的時候。檢查哪裏將此方法聲明.h文件中ANObject.h

+2

是的,由於循環依賴性,我得到了類似的錯誤。通過在接口文件中包含前向類聲明並在實現中導入頭文件來避免它。 –

+0

這對我更好:),謝謝! – mm24

22

導入你基本上@interface前添加

@class ANObject; 

+0

我不知道如何,但這解決了我的問題。 #import does not work and @class works .. – dreampowder

+0

好,它適合你:)總是樂於幫忙 – JomanJi

1

當變量類型拼寫錯誤時,我收到了此消息。請參閱下面的內容

例如

-(void)takeSimulatorSafePhotoWithPopoverFrame:(GCRect)popoverFrame { 

,而不是.....

-(void)takeSimulatorSafePhotoWithPopoverFrame:(CGRect)popoverFrame { 
+3

花了我足夠長的時間來弄清楚CGRect和GCRect的區別。 – OlivaresF

4

所以,出於某種原因而試圖設置方法與參數枚舉類型我得到這個錯誤。像這樣:

- (void)foo:(MyEnumVariable)enumVariable; 

我以前曾經這樣使用過它,從來沒有問題,但現在我做了。我檢查了循環依賴,並且找不到任何東西。我也多次檢查錯別字,沒有骰子。最終解決我的問題的是在我想訪問變量之前添加'枚舉'。像這樣:

- (void)foo:(enum MyEnumVariable)enumVariable; 
{ 
    enum MyEnumVariable anotherEnumVariable; 
} 
1

這聽起來很蠢,但炮擊錯誤或錯誤使用大/小寫letterwrong情況下,這個的。

+0

我討厭那些字母錯誤的情況! – DiscDev

0

奇怪的是,更改我的導入順序已經解決了這個問題...嘗試在所有其他導入後將導入移動到底部。