删除索引NSMutableArray处的对象

时间:2012-07-12 17:38:34

标签: objective-c xcode

  

可能重复:
  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没有崩溃)

3 个答案:

答案 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];