gpt4 book ai didi

iphone - NSManagedObjectContexts 和多线程

转载 作者:行者123 更新时间:2023-12-03 21:21:23 25 4
gpt4 key购买 nike

假设我们有一个应用程序需要显示地点列表并且在 3 个线程上运行:

  1. 主线程
  2. 主线程后台同步(同步有服务器的地方)
  3. 地理编码线程(对位置进行地理编码背景)

在所有 3 个线程中,我都有专用的 NSManagedObjectContexts(MOC)。如果每个 MOC 可以更改底层数据(例如,主线程可以将地点添加到您的收藏夹,而后台同步可以更改地点的名称,而地理编码线程添加 lat/lng 信息),则应用程序将必须注册 NSManagedObjectContextDidSaveNotification 在每个线程中,然后将 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 进行调用是否安全?因为这似乎可以解决它。我只是不知道,如果我不小心用这个打开了潘多拉魔盒......

问候,

塞巴斯蒂安

最佳答案

我认为您的应用程序结构使您处于危险境地。在我看来,竞争条件是在您从存储字典中删除 MOC 之前,某些线程“A”消失了。因此,您尝试在线程“A”上向它发送消息,它就会死掉。

而是这样想:

  • 每个线程都有一个线程本地对象,您可以将其存储在线程本地存储中(请参阅 NSThread 文档,查找 threadDictionary)
  • 该对象在您的线程开始执行工作时创建,并设置给定线程使用的 MOC
  • 该对象还注册保存通知,并在线程工作的生命周期内监视它们
  • 在线程工作结束时,该对象将被销毁。

通过这种方式,您可以封装托管对象上下文的生命周期,并将其直接绑定(bind)到引用它的通知机制。通过将监视器对象存储在线程本地存储中,您还可以将这两点关注点与线程的生命周期联系起来。

关于iphone - NSManagedObjectContexts 和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4259124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com