3

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

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

IE。

    //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了一个异步函数,我不能立即返回创建的对象;我必须使用一个块,这会有点混乱。有什么使用方法@synchronize吗?那会很好用吗?

4

2 回答 2

2

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

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

并发编程指南消除基于锁的代码部分概述了使用串行队列与传统锁定技术进行同步的一些基本原理。

Grand Central Dispatch (GCD) 参考并发编程指南中的调度队列讨论应该提供相当多的信息。

于 2013-04-26T21:09:16.580 回答
0

最简单的解决方案是将所有访问 dict 的代码都放在 @synchronized 块中。

串行操作队列很棒,但对我来说听起来有点矫枉过正,因为你没有保护整个数据生态系统,只是一个结构..

于 2013-04-23T13:37:36.240 回答