枚举时发生突变的数组

Posted

技术标签:

【中文标题】枚举时发生突变的数组【英文标题】:Mutated array while being enumerated 【发布时间】:2012-06-27 16:31:39 【问题描述】:

我得到的错误是

Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <CALayerArray: 0x7c85080> was mutated while being enumerated.'

我从NSGenericException 了解到的是,我在枚举时从数组中删除了一些东西。仍然知道这一点并环顾四周,我似乎无法解决我的问题。这是下面的代码。

-(void)tableView(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
     //Checks if message has been read. If message has not it updates the unreadMessages array
     if ([unreadMessage containsObject:[NSString stringWithFormat:@"m%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]] == TRUE && [[[storage_array objectAtIndex:indexPath.row] objectForKey:@"itemtype"] isEqualToString:@"message"]  == TRUE)

     //Unread
     [unreadMessage removeObject:[NSString stringWithFormat:@"m%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]];
     [unreadMessage writeToFile:[self saveUnreadMessages] atomically:YES];
     //Read
     [readMessage addObject:[NSString stringWithFormat:@"m%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]];
     [readMessage writeToFile:[self saveReadMessages] atomically:YES];
     [tableView reloadData];
 
 else if ([unreadNewsletter containsObject:[NSString stringWithFormat:@"n%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]] == TRUE && [[[storage_array objectAtIndex:indexPath.row] objectForKey:@"itemtype"] isEqualToString:@"newsletter"]  == TRUE)

     //Unread
     [unreadNewsletter removeObject:[NSString stringWithFormat:@"n%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]];
     [unreadNewsletter writeToFile:[self saveUnreadNewsletters] atomically:YES];
     //Read
     [readNewsletter addObject:[NSString stringWithFormat:@"n%@",[[storage_array objectAtIndex:indexPath.row] objectForKey:@"id"]]];
     [readNewsletter writeToFile:[self saveReadNewsletters] atomically:YES];
     [tableView reloadData];
 

【问题讨论】:

我确定您是在 for(... in ...) 循环中执行此操作的。你做不到。 您能否提供更多有关此代码执行位置的上下文?被变异的数组是一个 CALayerArray,它提示我进行一些 UI 更新;除了 tableView 重新加载之外,我看不到任何其他内容。这段代码发生在哪里? 这段代码发生在我的-(void)tableView(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 感谢@ctrahey,他确实得到了答案。我的 viewDidAppear 中有一个 NSThread 与主线程分离。在查找了更多信息后,我将其更改为主线程,一切都很好。 CALayerArray 是给我提示的东西。谢谢 【参考方案1】:

您不应该修改您正在迭代的数组。如果您打算这样做,您应该遍历它的副本:

for (id item in [array copy])

    …

(有 ARC。[[array copy] autorelease] 没有 ARC。)

如果需要,您可以在对其进行任何操作之前检查该项目是否仍在可变数组中。

【讨论】:

【参考方案2】:

或者,您可以在迭代原始可变数组时构建需要删除的对象的新 NSMutableArray,然后在循环完成后调用

[originalMutableArray removeObjects:newArrayContainingObjectsNeedingToBeRemoved];

【讨论】:

以上是关于枚举时发生突变的数组的主要内容,如果未能解决你的问题,请参考以下文章

UIImagePickerController - 枚举时集合发生突变

NSArrayM 在枚举时发生了突变

在目标 C 中枚举错误时,集合发生了突变

仅在发布模式下“枚举 NSArray 集合时发生突变”

集合 <__NSSetM: 0x14ea0160> 在枚举时发生了突变

集合 <__NSArrayM: 0x7fa1f2711910> 在枚举时发生了突变