iphone - 独立 ManagedObjectContext 中的 Coredata 对象故障与持久存储中的更改

标签 iphone cocoa-touch cocoa core-data nsfetchedresultscontroller

我有一个操作对象,它创建自己的托管对象上下文。操作对象执行计算基本上是为了减轻主线程的负载,而主线程则专注于 UI 方面。此操作对象的 MOC 在整个应用程序中共享一个公共(public)持久存储。

有时会发生这样的情况:在执行操作时,主线程的 MOC 会收到后端更改的通知。因此,我尝试合并 MOC 的更改,其中模型对象中的一些删除可能会发生。据我观察,在某些罕见的情况下,操作对象可能尚未实现,并且它们处于故障状态,同时主线程将更改存储到 MOC(以及持久存储)中。我的应用程序在这种情况下崩溃了。

根据标准文本,我的线程有一个专用的 MOC,并且根据我的理解,应该从线程的 MOC 访问故障数据。当同一对象可能已从存储中删除时,从线程的 MOC 访问错误请求是否会有所不同?

请查看此堆栈跟踪: enter image description here

处理这个问题更好的方法是什么?

我确实从这篇文章中了解到:https://stackoverflow.com/a/5722914/260665线程的托管对象上下文不知道存储底层的更改,并且错误的对象应该存在于存储中。因此,最好是:

  1. 当存储中存在任何基础更改(删除)时,使用 NSManagedObjectContextDidSaveNotification 更新线程中的对象集合。通知(来自:https://stackoverflow.com/a/5722914/260665)

  2. 检查是否NSManagedObject在尝试使用 -existingObjectWithID 访问其属性之前,其记录已存在于存储中在 MOC 上(来自:https://stackoverflow.com/a/14297708/260665)

  3. 处理代码中的异常? (最后的手段,来自:https://stackoverflow.com/a/15361906/260665)

我不可能继续使用解决方案 1 和 2,因为它不是直接访问 NSManagedObject 的属性,我有 NSFetchedResultController,它具有应用程序崩溃的排序描述符:

-(NSMutableArray*)fetchedTaskObjects
{
    if (nil==fetchedTaskObjects_ && self.taskLocalFetchedResultsController && self.persistantTaskFetchedResultsController)
    {
        NSArray *allNonPersistantTasks = [self.taskLocalFetchedResultsController fetchedObjects];
        NSArray *allPersistantTasks = [self.persistantTaskFetchedResultsController fetchedObjects];

        fetchedTaskObjects_ = [[NSMutableArray alloc] init];
        [fetchedTaskObjects_ addObjectsFromArray:allNonPersistantTasks];
        [fetchedTaskObjects_ addObjectsFromArray:allPersistantTasks];
        NSSortDescriptor *tasksSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.mockTaskCounter"
                                                                              ascending:YES];
        NSSortDescriptor *shortTextSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.shortText"
                                                                                  ascending:YES];
        NSSortDescriptor *headerTextSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.accountAssignmentText"
                                                                                   ascending:YES];
        [fetchedTaskObjects_ sortUsingDescriptors:[NSArray arrayWithObjects:tasksSortDescriptor, shortTextSortDescriptor, headerTextSortDescriptor, nil]];
    }
    return fetchedTaskObjects_;
}

那么有什么建议可以以正确的方式找到解决方案吗?

编辑: 我收到的错误(异常):

CoreData could not fulfill a fault for '0x2b0298a0 <x-coredata://E7E91AFC-5BE6-4996-B28F-92CD115A5D0A/CSTaskRegister/p14746>'

哪一行崩溃了?

它会在任何一个排序描述符中崩溃,其中排序描述符尝试访问损坏的托管对象的内部属性以进行排序。由于它是一个线程,我们不确定存储中的底层对象何时被删除。所以,我的统计计算代码有时也会出现线程崩溃的情况。

为什么要合并两个 FRC 的结果?

因为,该项目最初针对这两种情况使用了不同的 MOC,现在虽然 MOC 是单一的,但差异仍然存在。但我不认为拥有具有其自身用途的离散 FRC 是一个问题。

最佳答案

做了足够的研究,避免这种情况发生的唯一方法是通过监听通知来更新集合(问题中提到的第一个解决方案),另一种方法是仔细检查 -existingObjectWithID (有问题的第二个解决方案)在访问属性之前。

但就我而言,已删除(从持久存储中)托管对象的属性正在由排序描述符在内部访问。让我别无选择,只能处理线程中的异常(有问题的第三个解决方案)并忽略该线程的(错误)结果。

关于iphone - 独立 ManagedObjectContext 中的 Coredata 对象故障与持久存储中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18828164/

相关文章:

iphone - 文本在 iPhone 上的大小不正确

iphone - 用文本制作字母的算法

cocoa-touch - UINavigationController:将通用填充/边距应用于所有弹出 View Controller 的 View

objective-c - Objective-C 中的 NSString indexOf

objective-c - 如何扩展NSWindow的客户区?

iphone - Objective-c 类初始值设定项执行多次

ios - ios 中 cornerradius 中的段控制问题

ios - 无法解析基本的 JSON - iOS

cocoa-touch - UIAlertView按钮框架全为0?

swift - 归档项目后如何访问添加的 pdf 文件并将其复制到用户文档文件夹中?