7

Xcode 看着这一行并没有抱怨。项目建成,代码在运行时崩溃。

NSString *randomName = [NSString stringWithFormat:@"%@, %@, %@",
                         [randomAjectiveList objectAtIndex:ajectiveIndex],
                         [randomNounList objectAtIndex:nounIndex]];

自然地,仔细想想,我有一个太多的“ %@”,还有一个比实际争论更多的地方。正确的代码应如下所示

NSString *randomName = [NSString stringWithFormat:@"%@, %@",
                        [randomAjectiveList objectAtIndex:ajectiveIndex],
                        [randomNounList objectAtIndex:nounIndex]];

不过我问你……为什么 Xcode 没有抱怨?似乎与参数计数器有关。这不应该在编译时检查吗?也许它特定于“ %@”?

请指教。

4

1 回答 1

8

基于快速检查,您 100% 正确,在编译时没有检查这一点,即使是静态分析器也是如此。相反,检查 NSLog。所以在我的机器上,使用 XCode 4.0.2,如下:

[NSString stringWithFormat:@"%d %@ %@"];
NSLog(@"%d %@ %@");

在 NSLog 上产生“比数据参数更多 '%' 转换”的警告,但无法对 NSString 发表评论。

因此,区别可能是固定函数调用与动态调用。编译器实际上不能完全确定 NSString 调用将去哪里,因为您可能已经声明了一个类别或使用低级运行时在运行时调整 NSString 选择器表。

但是,特别是考虑到如果您开始修改 Foundation 类的行为,您几乎会立即遇到问题,就像您一样,我至少希望收到一个警告。

于 2011-07-04T22:03:20.673 回答