了解 Xcode 崩溃消息和 @synchronized 指令

Understanding Xcode crash message and @synchronized directive

尝试编写一些代码,除了使用全局变量单例之外,还使用 ​​iCloudKit 单例来跨多个方法调用共享变量和进程,可能来自多个 iPad。我有两个问题合二为一。

代码现在因这条消息而崩溃。

2015-06-09 18:31:18.879 iBeacons Demo[277:24157] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSDictionaryM: 0x17024fdb0> was mutated while being enumerated.'

*** First throw call stack:

(0x184a742d8 0x1960340e4 0x184a73c8c 0x100024b0c 0x185975f9c 0x184a2c240 0x184a2b4e4 0x184a29594 0x1849552d4 0x18e0336fc 0x18951afac 0x10005eacc 0x1966b2a08)

libc++abi.dylib: terminating with uncaught exception of type NSException

据我了解,这是尝试通过两种方法来更改可变字典对象的共享实例中的值。对 OOC 有点陌生,对多线程环境中的编程同样陌生,xCode 我有一个愚蠢的问题。

我如何追踪 NSMutableDictionary 对象 0x17024fdb0 在这里也引用了哪个?

假设我找到它 could/would 潜在的解决方法是使其 属性 声明像这样原子化,同时使用 @synchronized 指令。

所以我有...

property (retain, atomic) NSDictionary blah 

@synchronized(self) {
  // do something quickly
}

非常棒,

你说的都是对的,尽管公平地说,Tommy 的回复是引导我解决问题的答案。

for (NSString *student in studentNClass) {
if ([descriptions containsObject:student] ) {
    [studentNClass removeObjectForKey:student];
} else {
    [self addBeacon2Carousel:student];
    //singleBeaconsFound++;
    self.beaconsFound.text = [NSString stringWithFormat:@"%d",singleBeaconsFound];;
}

汤米之后..

for (NSString *student in [studentNClass allKeys]) {
    if ([descriptions containsObject:student] ) {
            [studentNClass removeObjectForKey:student];
    } else {
        [self addBeacon2Carousel:student];
        //singleBeaconsFound++;
        self.beaconsFound.text = [NSString stringWithFormat:@"%d",singleBeaconsFound];;
    }
}

谢谢!

这个问题的典型根源很简单,就是你在遍历数组(例如 for 循环或 enumerateObjectsWithBlock 或类似的东西)并尝试在仍然存在的情况下添加或删除对象遍历数组。这可能发生在最简单的单线程代码中,与同步多线程代码无关。

显然,如果您正在编写多线程代码,您也应该同步数组,无论如何,但这可能不是这里的问题。这个问题可能只是在改变数组的同时仍在 for 循环中迭代数组。


在您的回答中,您建议您删除所有字典 key/value 对,其键存在于另一个数组中。您当然可以使用 Tommy 建议的 allKeys 模式。或者,在这种情况下,使用 removeObjectsForKeys 可能更简单:

[students removeObjectsForKeys:descriptions];