gpt4 book ai didi

ios - -allKeys 后台线程导致错误 : __NSDictionaryM was mutated while being enumerated

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:38:51 24 4
gpt4 key购买 nike

我在后台线程上使用可变字典遇到了一个有趣的问题。

目前,我正在一个线程上分块下载数据,将其添加到数据集中,并在另一个后台线程上处理它。除了一个问题外,整体设计大部分工作正常:有时,对主数据集中内部字典的函数调用会导致以下崩溃:

*** Collection <__NSDictionaryM: 0x13000a190> was mutated while being enumerated.

我知道这是一个相当常见的崩溃,但奇怪的是它并没有在此集合的循环中崩溃。相反,Xcode 中的异常断点停止在以下行:

NSArray *tempKeys = [temp allKeys];

这让我相信一个线程正在向这个集合添加项目NSMutableDictionary-allKeys 的内部函数调用正在枚举键为了在另一个线程上返回数组

我的问题是:是这样吗?如果是这样,避免这种情况的最佳方法是什么?

这是我正在做的事情的要点:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

for (NSString *key in [[queue allKeys] reverseObjectEnumerator]) { //To prevent crashes

NEXActivityMap *temp = queue[key];
NSArray *tempKeys = [temp allKeys]; //<= CRASHES HERE
if (tempKeys.count > 0) {
//Do other stuff
}
}
});

最佳答案

您可以使用@synchronize。它会起作用的。但这是混淆了两种不同的想法:

  • 线程已经存在很多年了。一个新线程打开一个新的控制流。不同线程中的代码可能会同时运行,从而导致您遇到的冲突。为了防止这种冲突,您必须使用像 @synchronized 这样的锁。

  • GCD 是更现代的概念。 GCD 在“线程之上”运行,这意味着它使用线程,但这对您来说是透明的。你不必关心这个。在不同队列中运行的代码可能会同时运行,从而导致冲突。为防止这种冲突,您必须为共享资源使用一个队列。

您已经在使用 GCD,what is a good idea :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

使用线程的相同代码如下所示:

[[NSThread mainThread] performSelector:…];

因此,使用 GCD,您应该使用 GCD 来防止冲突。你正在做的是错误地使用 GCD,然后用锁“修复”它。

只需将对共享资源的所有访问(在您的例子中是 temp 引用的可变字典)放入串行队列。

  1. 在开始时为访问创建一个队列。这是一次性的。

您可以像在代码中那样使用现有队列之一,但您必须使用串行队列!但这可能会导致等待任务排长队(在您的示例 block 中)。串行队列中的不同任务一个接一个地执行,即使有空闲的 cpu 内核。因此,将太多任务放入一个队列并不是一个好主意。为任何共享资源或“子系统”创建一个队列:

dispatch_queue_t tempQueue;
tempQueue = dispatch_queue_create("tempQueue", NULL);
  1. 当代码想要访问可变字典时,将其放入队列中:

看起来像这样:

dispatch_sync( tempQueue, // or async, if it is possible
^{
[tempQueue setObject:… forKey:…]; // Or what you want to do.
}

您必须将访问共享资源的每个代码放入队列中,就像在使用线程时必须将每个访问共享资源的代码放入队列中一样。

关于ios - -allKeys 后台线程导致错误 : __NSDictionaryM was mutated while being enumerated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35878174/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com