我最近开始使用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
答案 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,并且您的代码位于自动释放池中!