【发布时间】:2010-11-23 17:49:19
【问题描述】:
假设我们有一个应用程序需要显示一个地点列表并在 3 个线程上运行:
- 主线程
- 主线程后台同步(同步 有服务器的地方)
- 地理编码 线程(对 背景)
在所有 3 个线程中,我都有专门的 NSManagedObjectContexts(MOC)。如果每个 MOC 都可以更改基础数据(例如,主线程可以将地点添加到您的收藏夹,而后台同步可以更改地点的名称,而地理编码线程会添加纬度/经度信息),则应用程序必须注册 @987654322 @ 在每个线程中,然后将mergeChangesFromContextDidSaveNotification 传播到其他线程中相应的其他 MOC,如果一个 MOC 被保存(不仅仅是将它们合并到主线程的 MOC 中),对吗???
因为我现在正在这样做,但感觉不对:(
我有一本字典,我用它来保存当前正在运行的线程及其 MOC。每当其中一个 MOC 弹出 NSManagedObjectContextDidSaveNotification 时,我都会遍历该数组并将 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 进行通话是否安全?因为这似乎可以解决它。我只是不知道,如果我不小心用这个打开了潘多拉的盒子......
问候,
塞巴斯蒂安
【问题讨论】:
标签: iphone multithreading core-data nsmanagedobjectcontext