这段代码对我有疑问,知道为什么? allButtons
是NSMutableArray
,其中包含3个对象a=0, b=1
,a和b为int
类型
if(a != -1 && b!= -1){
//Swap index in "allButtons"
id tempA = [allButtons objectAtIndex:a];
id tempB = [allButtons objectAtIndex:b];
[allButtons replaceObjectAtIndex:a withObject:tempB]; //Seg fault here?????
[allButtons replaceObjectAtIndex:b withObject:tempA];
needLoad = false;
[self setUpButtons];
}
编辑:
NSMutableArray *allButtons = //fetch the array from Coredata. This work since I display the data onto the screen, plus, [allButtons count] return 3, and a=0, b=1
f(a != -1 && b!= -1){
//Swap index in "allButtons"
[allButtons exchangeObjectAtIndex:a withObjectAtIndex:b];
needLoad = false;
[self setUpButtons];
}
答案 0 :(得分:22)
第一次调用replaceObjectAtIndex:
将释放旧对象(tempA
),但这不会导致seg错误。正如@Zoran所提到的,尝试记录retainCount
的tempA并验证其计数。
另外,对于数组中的元素交换,您应该使用exchangeObjectAtIndex:withObjectAtIndex
而不是replaceObjectAtIndex:withObject
。它受到iPhone 2.0的支持。
答案 1 :(得分:11)
只因为你说过
NSMutableArray *allbuttons = // something
并不意味着它肯定是一个NSMutableArray,它只是意味着编译器认为它将是一个NSMutableArray。
如果它来自CoreData,它可能只是一个NSArray
,所以你尝试的方法调用将无法工作 - 你会得到未经识别的选择器或类似的东西。
您必须先将其转换为可变数组
NSArray *coreData = // core data call
// Create a mutable copy
// NB This means that you are now working on a copy, not the original :)
NSMutableArray *allButtons = [coreData mutableCopy];
答案 2 :(得分:2)
tempA
时, replaceObjectAtIndex
将会被释放。在调用它时请记住这一点......我不知道为什么发布tempA
会为你设置错误,检查它的dealloc
可能是什么。
检查tempA
的保留计数,以便通过调用replaceObjectAtIndex
来验证它是否确实已被解除绑定(而不是简单地释放),如下所示:
id tempA = [allButtons objectAtIndex:a];
NSLog(@"retain count for tempA: %i", [tempA retainCount]);
如果您在此级别看到保留计数为1,那么您的对象tempA
将被replaceObjectAtIndex
答案 3 :(得分:0)
请阅读并理解object ownership上的Cocoa规则。请注意,您尚未声明对tempA和tempB引用的对象的所有权,因此您必须注意以下事项:
通常保证收到的对象在其收到的方法中保持有效...(虽然如果修改了从中接收另一个对象的对象,也必须小心)。该方法也可以安全地将对象返回给它的调用者。
基本上,行:
[allButtons replaceObjectAtIndex:a withObject:tempB];
可能会导致tempA被释放。这意味着后续行将导致allButtons向无效对象发送保留消息,因此出现seg错误。要解决此问题,您需要在交换之前保留tempA并将其释放或在之后自动释放。
注意忘记保留计数是明智的。除非您完全了解触摸对象的所有对象的实现,否则您无法对对象的保留计数进行任何假设。例如,没有规则说NSMutableArray的实现只会保留其元素一次。
答案 4 :(得分:0)
使用此方法传递appropritate索引
exchangeObjectAtIndex:withObjectAtIndex: