NSMutableAray RemoveObject:未按预期工作

时间:2013-06-15 04:33:34

标签: objective-c nsmutablearray

我最近开始使用cocoa和Objective-C,虽然我不是软件概念的新手,但我在NSMutableArray类中遇到了一些好奇和意想不到的行为。

首先,我使用Class'CustomClass'的自定义对象创建并填充'NSMutableArray'对象,该对象工作正常。然后我继续尝试删除其中一个对象,但我没有得到我想要的结果。

// NSMutableArray *Array is already initialized and loaded with 5 CustomClass Objects
//   stored in variables 'CustomClassObject1' through 'CustomClassObject5'. 
[Array removeObject:CustomClassObject4];

而不是这个代码只是删除第四个条目,如我所愿,它将第四个条目设置为'nil'(即,(id)0x00000000),更令人困惑的是,删除最后一个条目在数组中

根据我的理解,这不应该发生 - 所有应该发生的是第四个条目应该被删除,取而代之的是第五个条目。相反,我现在有一个包含三个对象和一个零的数组!

我也试过

int position = [Array indexOfObject:CustomClassObject4];
[Array removeObjectatIndex:position];

仅获得相同的结果。有谁知道为什么会这样?我误解了什么吗?

谢谢!

代码:

NSMutableArray *Array = [NSMutableArray array];

CustomClass *CustomClassObject1 = [[CustomClass alloc] init];
CustomClass *CustomClassObject2 = [[CustomClass alloc] init];
CustomClass *CustomClassObject3 = [[CustomClass alloc] init];
CustomClass *CustomClassObject4 = [[CustomClass alloc] init];
CustomClass *CustomClassObject5 = [[CustomClass alloc] init];

[Array AddObject:CustomClassObject1];
[Array AddObject:CustomClassObject2];
[Array AddObject:CustomClassObject3];
[Array AddObject:CustomClassObject4];
[Array AddObject:CustomClassObject5];

此时的输出:

_Array = (NSMutableArray *) 0x0885c2c0 @ "5 Objects"
[0] = (CustomClass *) 0x0885c5f0
[1] = (CustomClass *) 0x0885c630
[2] = (CustomClass *) 0x0885c690
[3] = (CustomClass *) 0x0885c6f0
[4] = (CustomClass *) 0x0885c730

然后:

[Array removeObject:CustomClassObject4];

此时的输出:

_Array = (NSMutableArray *) 0x0885c2c0 @ "4 Objects"
[0] = (CustomClass *) 0x0885c5f0
[1] = (CustomClass *) 0x0885c630
[2] = (CustomClass *) 0x0885c690
[3] = (id) 0x00000000

如果我删除了第3个对象,

[Array removeObject:CustomClassObject3];

然后输出:

_Array = (NSMutableArray *) 0x0885c2c0 @ "4 Objects"
[0] = (CustomClass *) 0x0885c5f0
[1] = (CustomClass *) 0x0885c630
[2] = (id) 0x00000000
[3] = (CustomClass *) 0x0885c6f0

2 个答案:

答案 0 :(得分:2)

这一切归结为ARC如何处理局部变量。有一会儿,我将假装关闭ARC以向您展示代码如何进行内存管理以用于说明目的:

NSMutableArray *Array = [NSMutableArray array];

//All of these are initialized with a +1 retain count
CustomClass *CustomClassObject1 = [[CustomClass alloc] init];
CustomClass *CustomClassObject2 = [[CustomClass alloc] init];
CustomClass *CustomClassObject3 = [[CustomClass alloc] init];
CustomClass *CustomClassObject4 = [[CustomClass alloc] init];
CustomClass *CustomClassObject5 = [[CustomClass alloc] init];

//The array retains what gets put into it, meaning it owns these variables
//And gives them a total reference count of +2
[Array AddObject:[CustomClassObject1 retain]];
[Array AddObject:[CustomClassObject2 retain]];
[Array AddObject:[CustomClassObject3 retain]];
[Array AddObject:[CustomClassObject4 retain]];
[Array AddObject:[CustomClassObject5 retain]];

//The compiler inserts a release for each of those objects because you
//Don't reference them before the method's scope ends.  The array still owns
//them, so they all have a total reference count of +1 at this point.
[CustomClassObject1 release];
[CustomClassObject2 release];
[CustomClassObject3 release];
[CustomClassObject4 release];
[CustomClassObject5 release];

当你删除一个对象时,该数组会减少它的引用计数,所以当你删除CustomClassObject4时,它的引用计数会下降到一个大的胖0,并且它会被释放。那是你看到的零。要解决此问题,请在强大的iVar,属性或全局范围内保留该方法范围之外的那些对象。

答案 1 :(得分:0)

请你尝试一些更简单的事情:

NSMutableArray *array = [NSMutableArray new];
[array addObject: [[CustomClass alloc] init] ];
// repeat for as many times you want.

// Fast enumerate the loop and get an output - You class will need to provide method id
for ( CustomClass * c in array ) NSLog( @"Class id: %@", [c id] );

// Then try to delete any random object.
[array removeObjectAtIndex: [array indexOfObject: object] ];

// And repeat the enumeration
for ( CustomClass * c in array ) NSLog( @"Class id: %@", [c id] );

请你试试看,告诉我们发生了什么事? 此外,在每次添加和删除操作时添加断点。

确保您已启用arc,并且您的代码位于自动释放池中!