【发布时间】:2023-03-24 02:45:01
【问题描述】:
尝试编写一些代码,使用 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 中的编程同样陌生,我有一个愚蠢的问题。
如何在此处追踪 0x17024fdb0 所指的 NSMutableDictionary 对象?
假设我发现它可以/将潜在的解决方法是使其属性声明像这样是原子的,同时使用 @synchronized 指令。
所以我有...
property (retain, atomic) NSDictionary blah
还有
@synchronized(self) {
// do something quickly
}
【问题讨论】:
-
这个问题的一个更典型的根源是您正在迭代一个数组(
for循环或enumerateObjectsWithBlock或类似的东西)并尝试添加或删除对象,同时仍然遍历数组。这可能发生在最简单的单线程代码中,并且与与多线程代码同步无关。如果您正在编写多线程代码,则无论如何都应该同步数组,但这不是问题的最可能根源。 (顺便说一句,这里不需要atomic,只需@synchronized或其他一些同步机制。) -
谢谢罗布;你是对的,我在通过它的同时从可变 NSDictionary 中删除了一个对象,尽管我仍然怀疑它必须执行多线程。会勾选你的答案......但你能告诉我我如何找到它在显示参考时崩溃的有问题的 NSDictionary,我怎样才能更容易地在 Xcode 中找到它?
-
@user3069232 打开 Xcode 左侧窗格中的“断点”选项卡,按底部的 +,选择“添加异常断点”。然后,当您下次在附加调试器的情况下运行并引发异常时,它将跳转到创建异常的行并允许您查询当前程序状态。一个通常在语义上正确的快速解决方法是将
for (x in dictionary)切换为for (x in [dictionary allKeys]),因为allKeys被声明为copy属性——所以你从开始迭代时开始迭代键的副本,而不是现场演出。
标签: ios xcode multithreading atomic synchronized