简体   繁体   English

Objective-C中出现意外的EXC_BAD_ACCESS

[英]Unexpected EXC_BAD_ACCESS in Objective-C

I have the following method: 我有以下方法:

-(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];
    }
}

The code runs as expected. 代码按预期运行。

However, if I comment out line (A) OR remove the ",nil" at the end of it, I get an EXC_BAD_ACCESS error at line (B)! 但是,如果我注释掉行(A)或删除它末尾的“,nil”,我会在行(B)处得到一个EXC_BAD_ACCESS错误! According to the debugger, the error occurs in CFRetain in the +[NSArray arrayWithObjects] built-in constructor. 根据调试器,错误发生在+ [NSArray arrayWithObjects]内置构造函数中的CFRetain中。

In addition, if I comment out line (A) and comment out the for(...) loop, the code runs through the method. 另外,如果我注释掉行(A)并注释掉for(...)循环,代码将贯穿该方法。

This is very unexpected to me. 这对我来说非常意外。 What am I doing wrong on line (B)? 我在线(B)做错了什么? And why would creating a completely different array on line (A) let the method run through? 为什么在线(A)上创建一个完全不同的数组让方法运行? And why does commenting out the for(...) loop prevent the error on line (B) that is before it? 为什么注释掉for(...)循环会阻止前面的行(B)上的错误?

Can someone explain why this is? 有人可以解释为什么会这样吗? Or at least give me some advice for debugging? 或者至少给我一些调试建议? I've already verified that the method is only running once and that "self" is valid. 我已经验证该方法只运行一次,“self”有效。

When using the convenience method arrayWithObjects , you must specify nil as the last element. 使用方便方法arrayWithObjects时 ,必须将nil指定为最后一个元素。

Documentation says: 文件说:

arrayWithObjects: arrayWithObjects:

Creates and returns an array containing the objects in the argument list. 创建并返回包含参数列表中对象的数组。

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

Parameters 参数

firstObj, ... firstObj,...
A comma-separated list of objects ending with nil. 以逗号分隔的以nil结尾的对象列表。

Add -Wformat to your Other Warning Flags and the compiler will pick up the missing nil for you. 添加-Wformat到您的其他警告标志,编译器将为您找到缺少的零。

The second one works after the first because the elements are all in the same position on the stack. 第二个在第一个之后工作,因为元素都在堆栈上的相同位置。 So after the return from the first one, the stack still contains a pointer to [NSNumber numberWithInt:1] , a pointer to [NSNumber numberWithFloat:2] and nil (and those pointers are even still valid since the autorelease pool hasn't been drained yet!). 所以从第一个返回后,堆栈仍然包含一个指向[NSNumber numberWithInt:1]的指针,一个指向[NSNumber numberWithFloat:2]和nil的指针(这些指针甚至仍然有效,因为自动释放池还没有耗尽了!)。 When you call the second one, without the nil, it replaces the pointers on the stack, but the nil is left unchanged. 当你调用第二个,没有nil时,它会替换堆栈上的指针,但是nil保持不变。 If your second attempt had had three numbers, it would likely have crashed in the same way, since the third number would have overwritten the nil and then whatever was next would be left. 如果你的第二次尝试有三个数字,它可能会以同样的方式崩溃,因为第三个数字将覆盖零,然后下一个将留下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM