Xcode looked at this line and did not complain. Project built, code crashed at runtime.
NSString *randomName = [NSString stringWithFormat:@"%@, %@, %@",
[randomAjectiveList objectAtIndex:ajectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
Naturally, come to think about it, i have one too many "%@
" in place, one more then actual arguments. Correct code should look as follows
NSString *randomName = [NSString stringWithFormat:@"%@, %@",
[randomAjectiveList objectAtIndex:ajectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
I ask you though ... why didn't Xcode complain? Seems like such an obvious thing to do with param counters. Shouldn't this be checked at compile time? Is it specific to "%@
", perhaps?
Please advise.
Based on a quick check, you're 100% right that this isn't checked at compile time, seemingly even by the static analyser. Conversely, NSLog is checked. So on my machine, with XCode 4.0.2, the following:
[NSString stringWithFormat:@"%d %@ %@"];
NSLog(@"%d %@ %@");
Produces a warning on the NSLog of "More '%' conversions than data arguments" but fails to comment on the NSString.
So, the difference could be fixed function calls versus dynamic calls. The compiler can't actually be completely certain where the NSString call will go because it's possible you'll have declared a category or used the low-level runtime to adjust the NSString selector table at runtime.
However, especially given the problems you'll almost immediately encounter if you start modifying the behaviour of the Foundation classes, like you I'd have expected at least a warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With