1

我有以下方法:

-(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",我会EXC_BAD_ACCESS在 (B) 行出现错误!根据调试器,错误发生在 +[NSArray arrayWithObjects] 内置构造函数中的 CFRetain 中。

另外,如果我注释掉行 (A) 并注释掉 for(...) 循环,则代码会运行该方法。

这对我来说是非常出乎意料的。我在 (B) 线上做错了什么?为什么会在 (A) 行创建一个完全不同的数组让该方法运行?为什么注释掉 for(...) 循环会阻止它之前的 (B) 行的错误?

有人可以解释这是为什么吗?或者至少给我一些调试建议?我已经验证了该方法只运行一次并且“self”是有效的。

4

2 回答 2

3

使用便捷方法arrayWithObjects时,必须将 nil 指定为最后一个元素。

文档说:

数组与对象:

创建并返回一个包含参数列表中对象的数组。

+ (id)arrayWithObjects: (id)firstObj, ...

参数

firstObj, ...
以 nil 结尾的以逗号分隔的对象列表。

于 2009-08-06T06:12:31.703 回答
1

将 -Wformat 添加到您的其他警告标志中,编译器将为您拾取丢失的 nil。

第二个在第一个之后起作用,因为元素都在堆栈上的相同位置。所以在从第一个返回之后,堆栈仍然包含一个指向 的指针[NSNumber numberWithInt:1]、一个指向[NSNumber numberWithFloat:2]和 nil 的指针(这些指针甚至仍然有效,因为自动释放池还没有被耗尽!)。当您调用第二个时,没有 nil,它会替换堆栈上的指针,但 nil 保持不变。如果你的第二次尝试有三个数字,它可能会以同样的方式崩溃,因为第三个数字会覆盖 nil,然后剩下的就是下一个数字。

于 2009-08-06T08:12:32.850 回答