2010-01-04 58 views
3

我有一個NSObject的子類實現了-(id)initWithRootElement:(MyElement *)e方法。 NSXMLDocument具有一個採用NSXMLElement的相同方法。當我編譯,我得到以下警告:無法弄清'警告:不兼容的Objective-C類型'

warning: incompatible Objective-C types 'struct MyElement *', expected 'struct NSXMLElement *' when passing argument 1 of 'initWithRootElement:' from distinct Objective-C type

在這種情況下,我與鏘+ LLVM對雪豹進行編譯和Xcode 3.2.1,不過這也與GCC 4.2發生在兩個豹紋雪豹。

我不明白爲什麼當NSXMLDocument必須先從NSXMLNode繼承時,它爲我的直接NSObject子類拋出警告?難道它不知道-(id)initWithRootElement:(NSXMLElement *)e僅適用於與我的課程無關的NSXMLDocument嗎?我可以理解,如果我試圖超負荷的方法,但我不是。請告訴我我不會發瘋......

#import <Foundation/NSAutoreleasePool.h> 
#import <Foundation/NSXMLElement.h> 
// Importing this here causes the warning... 
// #import <Foundation/NSXMLDocument.h> 

typedef NSObject MyElement; 

@interface TestClass : NSObject 
{ 
} 

- (id)initWithRootElement:(MyElement *)element; 
@end 

@implementation TestClass 
- (id)initWithRootElement:(MyElement *)element { return nil; } 
@end 

// ...but here it doesn't 
// #import <Foundation/NSXMLDocument.h> 

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

    // No warning! Inheritance: NSXMLDocument -> NSXMLNode -> NSObject 
    NSXMLElement *xmlElement = [[NSXMLElement alloc] initWithName:@"foo"]; 
    [[TestClass alloc] initWithRootElement:xmlElement]; 

    // warning: incompatible Objective-C types 'struct MyElement *', expected 'struct NSXMLElement *' when passing argument 1 of 'initWithRootElement:' from distinct Objective-C type 
    MyElement *element = [[MyElement alloc] init]; 
    [[TestClass alloc] initWithRootElement:element]; 

    [pool drain]; 
    return 0; 
} 

回答

11

Objective-C不支持協變聲明。

initWithRootElement:在NSXMLDocument聲明如下:

- (id)initWithRootElement:(NSXMLElement *)element; 

這是比你的聲明不同:

- (id)initWithRootElement:(MyElement *)element; 

在該參數的類型是不同的。這會導致混亂,這行代碼(其中elementMyElement *類型的...

[[TestClass alloc] initWithRootElement:element]; 

...因爲+alloc返回類型是id,因此,編譯器不知道使用哪種方法;哪個參數的類型是可以預期的

當使用Objective-C針對蘋果公司的框架代碼開發,經驗法則是從來沒有宣佈任何給定的選擇不同的參數

我。略感到驚訝的是,第一個案件也沒有警告。它可能應該。如果你有一個相當簡單的測試用例,請通過http://bugreport.apple.com/提交一個bug,然後在這個問題(或者我的回答)中附加bug#。

+0

謝謝Bill!我完全忘了+ alloc返回的id。現在完美。 我確實打算改變方法名稱,但當我無法弄清楚它爲什麼會警告我時會感到不安。 – 2010-01-04 04:55:52

+0

嗨@bbum,我希望你能對這種情況提供一點說明。 'id'類型有一個類型爲Class的'isa'指針,所以說objc不能遍歷類層次結構來找到合適的選擇器?即使從+ alloc返回'id',這種策略也可以在這種情況下工作,因爲這兩個類僅在層次結構頂部共享NSObject超類。謝謝! – rpj 2011-05-05 18:29:38

相關問題