假设我们有一个需要显示地点列表并在 3 个线程上运行的应用程序:
- 主线程
- 主线程后台同步(与服务器同步位置)
- 地理编码线程(在后台对地点进行地理编码)
在所有 3 个线程中,我都有专用的NSManagedObjectContexts
(MOC)。如果每个 MOC 都可以更改底层数据(例如,主线程可以将地点添加到您的收藏夹,而后台同步可以更改地点的名称,而地理编码线程添加纬度/经度信息),应用程序将必须NSManagedObjectContextDidSaveNotification
在每个mergeChangesFromContextDidSaveNotification
如果一个 MOC 被保存(而不仅仅是将它们合并到主线程的 MOC 中),则将其传播到其他线程中相应的其他 MOC,对吗???
因为现在我正在这样做,但感觉不对:(
我有一本字典,我用它来保存当前正在运行的线程及其 MOC。每当其中一个 MOC 弹出时,NSManagedObjectContextDidSaveNotification
I 循环通过该数组并将其发送mergeChangesFromContextDidSaveNotification
到所有其他 MOC/线程。当然,我还添加了一个观察者,NSThreadWillExitNotification
以便在其中一个线程用完时从数组中删除 Thread/MOC。字典的所有添加/删除操作都被锁定。这就是我现在有点卡住的地方。有时,当我打电话
[moc performSelector:@selector(mergeChangesFromContextDidSaveNotification:)
onThread:thread
withObject:notification
waitUntilDone:YES];
在遍历 MOC/线程字典时,我收到以下异常:
[NSManagedObjectContext performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform
显然,这是由竞争条件引起的。在遍历字典时(我只在提取其对象数组时锁定它),其中一个线程退出,因此引用不再有效。但是,如果我将字典锁放在整个循环的前面,我会遇到死锁,因为调用
[moc performSelector:@selector(mergeChangesFromContextDidSaveNotification:)
onThread:thread
withObject:notification
waitUntilDone:YES];
在某些情况下,循环内需要永远(还不知道为什么),从而导致整个应用程序停止。waitUntilDone:NO
在这种情况下打电话安全吗?因为这似乎可以解决它。我只是不知道,如果我不小心用这个打开了潘多拉的盒子......
问候,
塞巴斯蒂安