ios - NSMutableDictionary - EXC BAD ACCESS - 同时读/写

标签 ios objective-c multithreading nsmutablearray core-foundation

我希望对我的应用程序有所帮​​助。

我有一个设置,其中多个线程访问一个共享的 NSMutableDictionary由单例类拥有。线程访问字典以响应下载 JSON 并对其进行处理。单例类基本上可以防止某些具有唯一 ID 号的下载对象的重复。

即。

    //NSURLConnection calls:
    [[Singleton sharedInstance] processJSON:data];

@interface Singleton
+ (Singleton) sharedInstance;
@property (nonatomic, strong) NSMutableDictionary *store;
@end

@implementation

-(void) processJSON:(NSData*)data {
   ...
   someCustomClass *potentialEntry = [someCustomClass parse:data];
   ...
   if(![self entryExists:potentialEntry.stringId])
        [self addNewEntry:potentialEntry]; 
   ...
  }

-(void) entryExists:(NSString*)objectId {
    if(self.store[objectId])
     return true;
    else return false;
  }

 -(void) addEntry:(someCustomClass *object) {
    self.store[object.stringId] = object;
  }

一次可以有多达 5-10 个线程同时调用 processJSON。

不是立即,而是在运行几分钟后(在 iPhone 上比在模拟器上更快)我得到了可怕的 EXC BAD ACCESS。

我不承认我知道如何NSMutableDictionary有效,但我猜想在后台有某种哈希表需要在分配对象时更新并在访问对象时读取。因此,如果线程要立即读取/写入字典,则可能会发生此错误 - 可能是因为对象已在内存中移动?

希望有这方面知识的高手赐教!

至于解决方案,我正在考虑具有 NSOperationQueue 的单例类最大并发操作数为 1 然后使用 operationWithBlock:每当我想访问 NSDictionary .唯一的问题是它会调用 processJSON一个异步函数,我不能立即返回创建的对象;我必须使用一个 block ,那会有点困惑。有什么方法可以使用 @synchronize ?这样效果好吗?

最佳答案

我会提请您注意 Synchronization Hot Licks 向您指出的 线程编程指南 的 iOS 版部分。其中一种锁定机制或使用专用串行队列可以帮助您实现线程安全。

您对串行操作队列的直觉很有希望,尽管人们经常为此使用串行调度队列(例如,因此您可以从任何队列调用 dispatch_sync 到字典的串行队列),实现既是一种与其交互的受控机制,也是一种同步操作。或者,更好的是,您可以使用自定义并发队列(不是全局队列),并通过 dispatch_sync 执行读取并通过 dispatch_barrier_async 执行写入,从而实现高效的读写器方案(如 WWDC 2011 - Mastering GCDWWDC 2012 - Asynchronous Design Patterns 中所讨论)。

Eliminating Lock-Based Code 并发编程指南的部分概述了使用串行队列进行同步与传统锁定技术的一些基本原理。

Grand Central Dispatch (GCD) Referencedispatch queue discussion Concurrency Programming Guide 中应该提供了相当多的信息。

关于ios - NSMutableDictionary - EXC BAD ACCESS - 同时读/写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16137751/

相关文章:

iphone - Xcode 5 中的代码签名

c - gethostbyname() 进程即使在不同的线程中也能一致地解析吗?

c++ - Qt moveToThread 和数据竞争

ios - 从 iOS 应用程序运行 Haxe – hxRunLibrary() 错误

ios - 如何在 iOS 通用应用程序的 UIToolbar 中对齐 UIBarButtonItem?

ios - Objc - 以编程方式使用两个图像数组之一?

objective-c - 在NSArray中增加NSNumber

c++ - 如何匿名声明 std::thread?

iOS:如何检测弹出或关闭后是否出现viewcontroller

ios - 在Swift中将复杂的JSON保存到核心数据