了解 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];
尝试编写一些代码,除了使用全局变量单例之外,还使用 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];