ios - 在非主线程上设置一个大的 NSDictionary 属性

标签 ios objective-c multithreading nsdictionary grand-central-dispatch

我有一个名为 Dictionary 的类,其中 init 方法如下所示:

- (id) init{
    self = [super init];
    if (self){
        [self makeEmojiDictionaries];
    }

    return self;
}
- (void)makeEmojiDictionaries{

    //next line triggers bad_exc_access error 
    self.englishEmojiAllDictionary = @{@"hi" : @"👋"}; //this is a strong, atomic property of NSDictionary
};

我的问题是实际的表情符号字典非常大,我想使用 GCD 在非主线程 中完成所有繁重的工作。但是,每当我到达设置 self.englishEmojiAllDictionary 的那一行时,我总是会收到一个 bad_access 错误。

我尽可能以最正常的方式使用 GCD:

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
    dispatch_async(myQueue, ^{

        //Do long process activity
        Dictionary *dictionary = [[Dictionary alloc] init];

    });

GCD 或非主线程工作是否有我遗漏的特殊细微差别?非常感谢任何帮助 - 谢谢!

编辑 1:

如果您想自己尝试一下。我上传了一个 sample project复制此异常。我的理论是我正在初始化的 NSDictionary 太大了。

最佳答案

我已将您的数据从代码移动到 plist文件格式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>arancia meccanica</key><string>⏰🍊</string>
<key>uno freddo</key><string>🍺</string>
<key>un drink</key><string>🍸</string>
...
<key>bacio</key><string>💋</string>
<key>baci</key><string>💋👐</string>
</dict>
</plist>

(我获取了您的数据并使用了三次查找替换:", => </string>,然后是":@" => </key><string>@" => <key>)。

然后我使用以下方法加载了数据:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"dictionary" 
                                                     ofType:@"plist"]
dictionary = [NSDictionary dictionaryWithContentsOfFile:filePath];

这已经解决了问题。请注意,您永远不要将数据硬编码到源代码中。

这个错误的确切原因很难查明。 NSDictionary文字使用方法 +[NSDictionary dictionaryWithObjects:forKeys:count:] . 我的汇编程序知识很差,但我认为在调用这个初始化程序之前,所有的键和值都放在堆栈上。

但是,主线程的堆栈大小与后台线程的堆栈大小存在差异(参见 Creating Threads in Thread Programming Guide )。

这就是为什么在后台线程上执行代码时可以看到问题的原因。如果您有更多数据,该问题也可能会出现在主线程上。

主线程和后台线程栈大小的区别也可以通过下面的简单代码来说明:

- (void)makeEmojiDictionaries {
    // allocate a lot of data on the stack
    // (approximately the number of pointers we need for our dictionary keys & values)
    id pointersOnStack[32500 * 2];

    NSLog(@"%i", sizeof(pointersOnStack));
}

关于ios - 在非主线程上设置一个大的 NSDictionary 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36170176/

相关文章:

ios - 启动崩溃 iOS 应用程序

multithreading - Delphi2006 - 是否有带有 TMultiReadExclusiveWriteSynchronizer 的 TList?

ios - 快速滑动 View

ios - 无法从服务器 api 解析 JSON

ios - UIFontMetrics : scaled font size calculation

objective-c - -[GMSMapView animateToCameraPosition :]: unrecognized selector sent to instance

iOS >> 更改方向时获取当前可见 View /窗口大小

iphone - 在 iOS(某些版本)中切换声音音量时不一致的 OpenAL 爆音伪像

java - 私有(private)锁对象和内在锁

c++ - 插入双映射的线程