简体   繁体   English

NSMutableArray删除对象,但应用程序崩溃

[英]NSMutableArray removing the object but then app crashes

I have what I think is a weird error but of course i'm relatively new to iPhone Development so it's possible that it's not all that weird after all. 我有一个我认为是奇怪的错误,但是我当然对iPhone开发而言还比较陌生,因此可能毕竟不是那么奇怪。

I have an array (NSMutableArray) of objects that I am keeping track of (one is added to the array every time the user touches a button) what I'm trying to do is when the array reaches a certain value I add the new object to the beginning of the array and then remove the last object in the array. 我有一个要跟踪的对象数组(NSMutableArray)(每次用户触摸按钮时都会向该数组添加一个对象),我想做的是当数组达到某个值时我添加新对象到数组的开头,然后删除数组中的最后一个对象。 When I step through my code everything works the object is removed but then the app just crashes...the debugger isn't on any line of code when the app crashes and there are no loops or timers in the app yet so I can't think of anything else that is running. 当我单步执行代码时,所有工作正常的对象均被删除,但是应用程序崩溃了……当应用程序崩溃时,调试器不在任何代码行上,并且应用程序中还没有循环或计时器,因此我可以想不到正在运行的任何其他东西。

here is the code that is executed right before the crash 这是崩溃之前立即执行的代码

if([objectArray count] > 10)
{
    MyObject *objectToRemove = [[MyObject alloc] init];
    objectToRemove = [objectArray objectAtIndex:10];
    [objectArray removeObjectAtIndex:10];
    [objectToRemove removeFromSuperview];
}

the main point of this code is that everytime the user touches a button an object is added to the screen and displayed, and then when the number of objects reaches 10 and the user touches the button again the first object that was added is removed and the new object is displayed. 该代码的主要要点是,每次用户触摸按钮时,都会将一个对象添加到屏幕上并显示,然后当对象数达到10并且用户再次触摸该按钮时,将删除添加的第一个对象,并且显示新对象。 If I comment out the removeObjectAtIndex line everything works as intended but the array continues to grow. 如果我注释掉removeObjectAtIndex行,那么一切都会按预期进行,但是数组会继续增长。

I've also tried removing the object after the UIview is removed and the app behaves the same way. 我也尝试过在删除UIview之后删除对象,并且应用程序的行为方式相同。 If I try to remove an object from the array at a different index (IE 3) the app doesn't crash but it doesn't give me my expected result. 如果我尝试从另一个索引(IE 3)的数组中删除一个对象,则该应用程序不会崩溃,但是并不能达到预期的效果。 but like I said the code runs fine and when I check the count of the array before and after the execution of the line the value is 11 and 10 respectively. 但是就像我说的那样,代码运行良好,当我在执行该行之前和之后检查数组的计数时,该值分别为11和10。

Any help you can provide would be appreciated, 您能提供的任何帮助将不胜感激,

BWC 《生物武器公约》

I don't think this does what you think it does. 我认为这并没有您认为的那样。 Going line by line: 逐行:

MyObject *objectToRemove = [[MyObject alloc] init];

You allocate a new object of type "MyObject. 您分配类型为“ MyObject”的新对象。

objectToRemove = [objectArray objectAtIndex:10];

You overwrite your local MyObject pointer with whatever was at index 10 in objectArray. 您用objectArray的索引10处的内容覆盖了本地MyObject指针。 The objectToRemove that you initially allocated is now leaked. 您最初分配的objectToRemove现在泄漏了。

 [objectArray removeObjectAtIndex:10];

Now you've removed the object at index 10. When you remove it from the array, it is released and its reference count is decremented. 现在,您已在索引10处删除了该对象。将其从数组中删除时,该对象将被释放,并且其引用计数将减少。 This may (or may not) cause it to be deallocated. 这可能会(也可能不会)导致它被释放。

 [objectToRemove removeFromSuperview];

Now you are sending a message to the object that was previously in the objectArray. 现在,您正在向对象数组中以前的对象发送一条消息。 If the object was deallocated by the previous line of code, I would expect a crash. 如果对象由上一行代码释放,则可能会发生崩溃。

Putting aside the leak in the declaration, you might be able to do this: 在声明中撇开泄漏,您可以执行以下操作:

        objectToRemove = [[objectArray objectAtIndex:10] retain];
        [objectArray removeObjectAtIndex:10];
        [objectToRemove removeFromSuperview];
        [objectToRemove release];

This would prevent the object from being deallocated out from under you, if that's why the crash is happening. 如果这就是崩溃发生的原因,这将防止从您下方释放该对象。

One way to determine if my scenario is what is happening is to turn on NSZombies, which you can do by setting the environment variable NSZombieEnabled to YES. 确定我的场景是否正在发生的一种方法是打开NSZombies,可以通过将环境变量NSZombieEnabled设置为YES来完成。

How about: 怎么样:

MyObject *objectToRemove = [objectArray objectAtIndex:10];
[objectToRemove removeFromSuperview];
[objectArray removeObjectAtIndex:10];

removeFromSuperview will decrement the retain count once on objectToRemove. removeFromSuperview将对objectToRemove减少一次保留计数。 (removeFromSuperview implies that it was added to the view previously and that had retained it and incremented its retain count by one). (removeFromSuperview意味着它先前已添加到视图中,并且已经保留了该视图,并将其保留计数增加了一个)。 removeObjectAtIndex will decrement it again. removeObjectAtIndex会再次减少它。 But in this order, you most likely will not be releasing it when you still need it around. 但是按照这种顺序,当您仍然需要它时,您很可能不会释放它。 (Of course, adding to the array also retained it so the order may not be that important). (当然,添加到数组也会保留它,因此顺序可能并不那么重要)。

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

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