gle*_*rey 43 collections cocoa cocoa-touch objective-c nsmutablearray
我有一个NSMutableArray存储用于Box2d物理模拟的鼠标接口.当使用多个手指播放时,我会得到例外陈述
NSArray在被枚举时发生了变异
我知道这是因为我正在从数组中删除对象,同时也通过它枚举,使枚举无效.
我想知道的是,解决这个问题的最佳策略是什么?我在网上看到了一些解决方案:@synchronized在枚举或将触摸关节放入垃圾数组之前复制数组以便以后删除(我不确定是否可行,因为我需要在移除后直接从数组中删除鼠标点它来自世界).
dan*_*ndi 47
您始终可以在没有枚举器的情况下进行迭代.这意味着一个常规的for循环,当你删除一个对象时: - 递减索引变量并继续; .如果在进入for循环之前缓存数组的计数,那么确保在删除对象时也减少该数量.
无论如何,我不明白为什么带有对象以便以后删除的数组会出问题.我不知道你所拥有的确切情况和涉及的技术,但理论上应该没有问题.因为在大多数情况下使用此方法时,您只能在第一次枚举中执行任何操作,并在枚举删除数组时执行实际操作.如果您遇到的情况是,在第一个枚举中您再次针对同一个数组检查某些内容,并且您需要知道对象不再存在,您可以添加一个检查以查看它们是否在删除数组中.
无论如何,希望我帮助.祝好运!
edc*_*591 37
你可以这样做:
NSArray *tempArray = [yourArray copy];
for(id obj in tempArray) {
//It's safe to remove objects from yourArray here.
}
[tempArray release];
Run Code Online (Sandbox Code Playgroud)
mar*_*ker 33
最简单的方法是向后枚举数组,这意味着删除对象时下一个索引不会受到影响.
for (NSObject *object in [mutableArray reverseObjectEnumerator]) {
// it is safe to test and remove the current object
if (AddTestHere) {
[savedRecentFiles removeObject: object];
}
}
Run Code Online (Sandbox Code Playgroud)
锁定(@synchronized)操作比一遍又一遍地复制整个数组要快得多.当然,这取决于数组有多少元素,以及执行的频率.想象一下,你有10个线程同时执行这个方法:
- (void)Callback
{
[m_mutableArray addObject:[NSNumber numberWithInt:3]];
//m_mutableArray is instance of NSMutableArray declared somewhere else
NSArray* tmpArray = [m_mutableArray copy];
NSInteger sum = 0;
for (NSNumber* num in tmpArray)
sum += [num intValue];
//Do whatever with sum
}
Run Code Online (Sandbox Code Playgroud)
它每次复制n + 1个对象.你可以在这里使用lock,但如果有100k元素要迭代怎么办?在迭代完成之前,数组将被锁定,其他线程必须等到锁被释放.我认为在这里复制对象更有效,但它还取决于该对象的大小以及您在迭代中做了什么.锁应始终保持最短的时间.所以我会使用锁来做这样的事情.
- (void)Callback
{
NSInteger sum = 0;
@synchronized(self)
{
if(m_mutableArray.count == 5)
[m_mutableArray removeObjectAtIndex:4];
[m_mutableArray insertObject:[NSNumber numberWithInt:3] atIndex:0];
for (NSNumber* num in tmpArray)
sum += [num intValue];
}
//Do whatever with sum
}
Run Code Online (Sandbox Code Playgroud)