我有以下方法:
-(void)testAPIModule {
self.requests = [NSMutableArray array];
NSLog(@"making arrays");
/*(A)*/ id array1 = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithFloat:2], nil];
/*(B)*/ id array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:4], [NSNumber numberWithInt:5]];
NSLog(@"made array=%@",array2);
for( ServerRequest *req in self.requests ) {
[Networker sendRequest:req withDelegate:self];
[req release];
}
}
代码按预期运行。
但是,如果我注释掉行(A)或删除它末尾的“,nil”,我会在行(B)处出现EXC_BAD_ACCESS
错误!根据调试器,错误发生在+ [NSArray arrayWithObjects]内置构造函数中的CFRetain中。
此外,如果我注释掉行(A)并注释掉for(...)循环,代码将贯穿整个方法。
这对我来说非常意外。我在线(B)做错了什么?为什么在线(A)上创建一个完全不同的数组让方法运行?为什么注释掉for(...)循环会阻止它之前的行(B)上的错误?
有人可以解释为什么会这样吗?或者至少给我一些调试建议?我已经验证该方法只运行一次并且“self”有效。
答案 0 :(得分:3)
使用方便方法 arrayWithObjects 时,必须将nil指定为最后一个元素。
文档说:
<强> arrayWithObjects:强>
创建并返回一个包含参数列表中对象的数组。
+ (id)arrayWithObjects: (id)firstObj, ...<强>参数强>
firstObj,...
结尾
以逗号分隔的对象列表,以nil。
答案 1 :(得分:1)
将-Wformat添加到您的其他警告标志中,编译器将为您挑选缺失的零。
第二个在第一个之后工作,因为元素都在堆栈上的相同位置。所以在从第一个返回之后,堆栈仍然包含一个指向[NSNumber numberWithInt:1]
的指针,一个指向[NSNumber numberWithFloat:2]
和nil的指针(这些指针甚至仍然有效,因为自动释放池还没有耗尽!)。当你调用第二个,没有nil时,它会替换堆栈上的指针,但是nil保持不变。如果你的第二次尝试有三个数字,它可能会以同样的方式崩溃,因为第三个数字会覆盖零,然后下一个将被留下。