可能重复:
Objective-C NSMutableArray mutated while being enumerated?
我使用此代码删除索引处的对象:
-(IBAction)deleteMessage:(id)sender{
UIButton *button = (UIButton*) sender;
for (UIImageView *imageView in imageArray)
{
if ([imageView isKindOfClass:[UIImageView class]] && imageView.tag == button.tag)
{
if (imageView.frame.size.height == 60) {
x = 60;
}
if (imageView.frame.size.height == 200) {
x = 200;
}
for (UITextView *text in messagetext)
{
for (UITextView *name in messagename)
{
if ([text isKindOfClass:[UITextView class]] && text.tag == button.tag && text.tag== name.tag)
{
[imageView removeFromSuperview];
[messagename removeObjectAtIndex:button.tag - 1];
[messagetext removeObjectAtIndex:button.tag - 1];
}
}
}
错误是:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x704bdb0> was mutated while being enumerated.'
我注意到,如果我先删除数组中的最后一个对象,并按顺序从最后一个到第一个,它就可以了。但是,如果我尝试删除不是最后一个索引的对象,应用程序崩溃并给出错误:(1,2,3,4..I delete object2 ... crash ...如果我删除对象4没有崩溃)
答案 0 :(得分:7)
执行此操作的一种方法是创建一个包含要删除的索引的数组,然后执行循环,添加索引并在之后删除对象。像这样:
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
// Inside your loop
[indexes addIndex:(button.tag - 1)];
//..
// After your loop
[messagename removeObjectsAtIndexes:indexes];
[messagetext removeObjectsAtIndexes:indexes];
现在,如果您想为两个数组添加不同的索引,只需创建另一个NSMutableIndexSet
并向其添加第二组索引。如果您不使用ARC,也不要忘记释放indexes
。
答案 1 :(得分:1)
如果您计划对其进行变异(即删除元素),则不能对数组使用“for each”样式迭代,因为它会与迭代混淆。如果你真的想在迭代它时从数组中删除一个元素,你需要使用“旧样式”迭代。另一个Stack Overflow帖子here很好地展示了如何使用允许你改变数组的旧样式。
答案 2 :(得分:1)
如果从中插入或删除对象,则不能在数组上使用“for x in y”迭代。 要么你必须使用一个好的'时尚阵列,要么你可以保留对你要删除的对象的引用,然后删除它:
NSObject *messageNameToRemove;
NSObject *messageTextToRemove;
for (UITextView *text in messagetext)
{
for (UITextView *name in messagename)
{
if ([text isKindOfClass:[UITextView class]] && text.tag == button.tag && text.tag== name.tag)
{
[imageView removeFromSuperview];
messageNameToRemove = [messagename objectAtIndex:button.tag -1];
messageTextToRemove = [messagetext objectAtIndex:button.tag -1];
}
}
[messagename removeObject:messageNameToRemove];
[messagetext removeObject:messageTextToRemove];