我刚刚注意到,如果您尝试在 alloc 语句所在的同一行调用不存在的 init 方法,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 方法分成两行不同的代码来获得编译器警告,但我从未见过这样做;我总是学会使用一行代码来分配和初始化。
首先,有趣的问题!
XCode 使用 gcc 输出来创建警告和错误列表,并使用其他一些(内部)机制来创建自动完成建议列表。自动完成有时更聪明(有时则不然,你知道:)
但是为什么gcc不报告警告呢?您已经有了答案 -
alloc
返回 id
。
我的回答不是‘答案’,但我想跟大家分享下。 (抱歉,我暂时没有Mac,所以不是Apple的objective-c)
shum@shum-laptop:/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;
}
shum@shum-laptop:/tmp/shum$ gcc test.m -lobjc
shum@shum-laptop:/tmp/shum$
无警告。但尝试在
- (id) blah
界面评论
Test1
shum@shum-laptop:/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.)
shum@shum-laptop:/tmp/shum$
可以得出一个结论:如果你在调用init时输入错误并且没有同名的选择器,那么gcc应该警告你;在不好的情况下,当某处存在同名选择器时,gcc 不会警告您。我暂时没有Mac和XCode,可以测试一下吗?
[编辑] 刚刚用xcode测试了一下。同样的行为。