如何在NSMutableArray中交换值?

时间:2010-04-07 04:38:48

标签: iphone objective-c nsmutablearray

这段代码对我有疑问,知道为什么? allButtonsNSMutableArray,其中包含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];
 }

5 个答案:

答案 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: