【问题标题】:Core Data: Deleting causes 'NSObjectInaccessibleException' from NSOperation with a reference to a deleted object核心数据:从 NSOperation 中删除会导致“NSObjectInaccessibleException”,并引用已删除的对象
【发布时间】:2012-05-20 19:59:15
【问题描述】:

我的应用程序有NSOperation 子类来获取和操作托管对象。我的应用程序还会定期从数据库中清除行,这可能会导致以下竞争条件:

  • 后台操作获取一堆对象(从特定于线程的上下文中)。它将遍历这些对象并使用它们的属性做一些事情。
  • 在主托管对象上下文中删除了一堆行。
  • 后台操作访问从主上下文中删除的对象的属性。这导致'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault'

理想情况下,NSOperation 获取的对象可以在上操作,即使在主上下文中删除了一个对象。我认为实现这一目标的最佳方法是:

  • 调用[request setReturnsObjectsAsFaults:NO] 以确保Core Data 不会尝试为不再存在于主上下文中的对象执行故障。这里的问题是我可能需要访问对象的关系,这(据我了解)仍然会出错。
  • 预先遍历托管对象并将我需要的属性复制到单独的非托管对象中。这里的问题是(我认为)我需要同步/锁定这部分,以防在完成复制之前在主上下文中删除了一个对象。

我是否遗漏了一些明显的东西?看起来我想要完成的事情并没有太不寻常。感谢您的帮助。

【问题讨论】:

    标签: core-data concurrency nsmanagedobject nsmanagedobjectcontext nsoperation


    【解决方案1】:

    你说每个线程都有自己的上下文。那挺好的。但是,它们还需要与彼此的更改保持同步(如何取决于它们的层次结构)。

    是全部分配给同一个持久存储协调器,还是它们具有父/子关系?

    兄弟姐妹应该监控来自其他兄弟姐妹的 NSManagedObjectContextObjectsDidChangeNotification。当子上下文保存时,父母会自动收到通知。

    【讨论】:

      【解决方案2】:

      我最终通过在同一个队列上执行提取和删除来缓解这个问题。

      【讨论】:

        【解决方案3】:

        很好的问题,我只能提供部分答案,我也很想知道这一点。不幸的是,您自己的解决方案更多的是一种解决方法,但并不是真正的答案。如果后台操作很长,又不能在主线程上运行怎么办?

        我可以说的一件事是您不必调用[request setReturnsObjectsAsFaults:NO],因为提取请求会将数据加载到行缓存中,并且当某个提取的对象发生故障时不会返回数据库(请参阅 Apple 的 NSFetchRequest 文档)。不过,这对人际关系没有帮助。

        我尝试了以下方法:

        1. NSManagedObjectContextWillSave 通知上,等待当前后台任务完成并阻止新任务以类似的方式开始

          -(void)contextWillSave:(NSNotification *)notification {
              dispatch_sync(self.backgroundQueue, ^{
                  self.suspendBackgroundOperation = YES;
              });
          }
          
        2. NSManagedObjectContextDidSave 通知上取消设置suspendBackgroundOperation

        但是 dispatch_sync 调用引入了可能的死锁,所以这也不起作用(参见my related question)。此外,它仍然会阻塞主线程,直到可能冗长的后台操作完成。

        【讨论】:

          猜你喜欢
          • 2020-03-26
          • 2016-11-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多