2010-11-02 81 views
4

我刚刚注意到,如果您尝试在alloc语句的同一行调用不存在的init方法,XCode不会警告您这一点。Xcode不会为无效的初始化方法发出警告

NSString *string = [[NSString alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 
UIView *view = [[UIView alloc] initWithCapacity:0]; 

这两行代码都没有警告。现在,我想这是因为“alloc”实际上返回id,而不是静态类型。但是,当我开始键入“init”时,XCode为我提供了自动完成选项,其中只包含正确类型的init方法。所以,如果它是在行的开始处使用我的静态类型来给我提供自动完成选项,为什么它不会使用它来给我一个警告?这是XCode中可以打开的设置吗?

显然,这并不重要,多的明显错误之类的那些例子,但对于某些对象,这可能会导致由于拼写错误或忘记改变一两件事,当你改变的另一件事运行时错误。我还可以通过将alloc和init方法分成两行不同的代码来获得编译器警告,但我从来没有见过这样做;我一直学会使用一行代码来进行alloc和init。

回答

3

首先,有趣的问题!

XCode使用gcc输出创建警告和错误列表以及其他一些(内部)机制来创建自动填充建议列表。自动完成有时更聪明(有时候不是,你知道:)

但为什么gcc不报警?您已经有一个答案 - alloc返回id

我的回答不是'答案',但我想与你分享下。 (对不起,我暂时没有Mac,所以它不是苹果的目标-c)

[email protected]:/tmp/shum$ cat test.m 

#import <objc/Object.h> 

@interface Test1 : Object 
{ 
} 

- (id) blah; 

@end 

@interface Test : Object 
{ 
} 

@end 

@implementation Test 

@end 

int main() 
{ 
    Test* test = [[Test alloc] blah]; 
    return 0; 
} 

[email protected]:/tmp/shum$ gcc test.m -lobjc 
[email protected]:/tmp/shum$ 

没有警告。但试评- (id) blahTest1接口

[email protected]:/tmp/shum$ gcc test.m -lobjc 
test.m: In function ‘main’: 
test.m:24: warning: no ‘-blah’ method found 
test.m:24: warning: (Messages without a matching method signature 
test.m:24: warning: will be assumed to return ‘id’ and accept 
test.m:24: warning: ‘...’ as arguments.) 
[email protected]:/tmp/shum$ 

可以做一个结论:如果你犯了一个错字调用init和存在具有相同名称的选择,那么GCC应该提醒你;在不好的情况下,当某个名字相同的选择器存在时,gcc不会警告你。我暂时没有Mac和XCode,请你测试一下吗?

[编辑] 刚刚用xcode进行了测试。同样的行为。

+0

谢谢;我注意到在这之前,编译器会根据它可以找到的项目范围的方法给出警告。我希望有一些设置可以使编译器警告与自动完成一样“智能”。这对于Xcode来说应该是一件非常简单的事情!伪代码:if(!autoCompleteList.contains(methodName))warn();还值得一提的是,这个问题的真实目的是因为我用UIActionSheet替换了一个UIAlert,它具有相似但不同的init方法。当我忘记更改init方法后,我没有被警告,我很惊讶。 – GendoIkari 2010-11-03 13:51:25