Objective-C NSMutableArray在枚举时发生变异?

See*_*rex 37 iphone xcode objective-c

我有点偶然发现了一个错误,你尝试从NSMutableArray中删除对象,而其他对象被添加到其他地方.为了简单起见,我不知道如何修复它.这是我正在做的事情:

我有4个定时器调用4个不同的方法,将对象添加到同一个数组.现在,当我按下某个按钮时,我需要删除阵列中的所有对象(或至少一些).所以我试图首先使所有4个计时器无效,然后用数组做我想要的工作,然后启动计时器.我认为这会有用,因为我不再使用计时器来枚举数组,但看起来它不起作用.

这里有什么建议?

dea*_*rne 110

这与你的计时器无关.因为(我假设)你的计时器都在与修改方法相同的线程上工作,所以你不需要停下来启动它们.iOS没有使用中断模型进行计时器回调,他们必须像其他任何事件一样等待轮到他们:)

你可能正在做类似的事情

for (id object in myArray)
   if (someCondition)
       [myArray removeObject:object];
Run Code Online (Sandbox Code Playgroud)

你不能编辑一个可变数组,所以你需要创建一个临时数组来保存你想要删除的东西

// Find the things to remove
NSMutableArray *toDelete = [NSMutableArray array];
for (id object in myArray)
   if (someCondition)
       [toDelete addObject:object];

// Remove them
[myArray removeObjectsInArray:toDelete];
Run Code Online (Sandbox Code Playgroud)


fer*_*tar 24

你可以这样做:

for (id object in [myArray copy])
   if (someCondition)
       [myArray removeObject:object];
Run Code Online (Sandbox Code Playgroud)

就像@deanWombourne所说的那样,"当你经历它时你不能编辑一个可变数组",所以我在这里做的是创建一个自动释放的原始数组副本来枚举对象,这样你就可以安全地删除任何你想要的.

更清晰,更少的锅炉代码(我认为!).

更新:删除自动释放呼叫,因为这是一个旧答案,ARC之前.

  • 嗨@pxpgraphics - 如果你正在做一个`for(n = 0; n <myArray.copy.count; ++ n){...}`样式循环,那么你是对的.但是,快速迭代不能像那样工作 - 它枚举数组的所有项_once_然后传递它们 - (一篇好文章[这里] [http://nshipster.com/enumerators/]).因此,在这种情况下,优化不会加快速度.它可能会使代码更具可读性,这总是一件好事. (2认同)

Nik*_*und 5

您可以使用@synchronized()指令在变异时锁定该数组:

if (someCondition) {
    @synchronized(yourArray) {
        [yourArray removeObject:someObject];
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocThreading.html