【问题标题】:CoreData could not fulfill a fault for when objects are updated by HTTP service当 HTTP 服务更新对象时,CoreData 无法完成错误
【发布时间】:2013-07-04 16:20:03
【问题描述】:

我想我理解错误信息:CoreData 无法完成错误,但我不确定应该如何处理。

我们有一个应用程序,我们在其中使用 Core Data 来持久化从 JSON 服务返回的数据。今天我正在做以下事情。

  1. 从持久存储中获取本地对象并返回 UI
  2. 询问服务器对象是否已更新 - 当我得到答案时,我会更新 Core Data 托管对象
  3. 使用更新后的对象更新 UI

问题是;即使我不使用多线程,当 HTTP 请求删除我的 UI 保留的托管对象时,有时也会出现错误。我试图用returnObjectsAsFaults 来获取对象为NO。我想我可以访问托管对象的所有关系和属性,即使它被删除(只要我的 UI 保留了它)。

我应该如何解决这个问题?

我认为我可以使用单独的 NSManagedObjectContext 进行读写。我做了这个测试:

MyAuthorMO *authorUpdate = [[MyAuthorMO alloc] init]; // I have made this init insert the object into the updateContext
authorUpdate.firstname = @"Hans";
authorUpdate.lastname = @"Wittenberg";
authorUpdate.email = @"Hans@somedomain.no";

NSManagedObjectContext *updateContext = [[MyCoreManager getInstance] managedObjectContext];

NSError *error = nil;
[updateContext save:&error];

NSManagedObjectContext *readContext = [[MyCoreManager getInstance] readOnlyContext];

NSFetchRequest *fetchRequest = [managedObjectModel fetchRequestFromTemplateWithName:@"authorByEmail" substitutionVariables:[NSDictionary dictionaryWithObject:@"Hans@somedomain.no" forKey:@"EMAIL"]];
[fetchRequest setReturnsObjectsAsFaults:NO];

NSArray *authors = [readContext executeFetchRequest:fetchRequest error:&error];

MyAuthorMO * readAuthor = [authors objectAtIndex:0];

// Delete the author with update context:
[updateContext deleteObject:authorUpdate];
[updateContext save:&error];

NSLog(@"Author: %@ %@, (%@)", readAuthor.firstname, readAuthor.lastname, readAuthor.email);

只要我使用 readContext 进行获取,日志就会很好地输出。如果我使用 updateContext 进行提取,则会出现异常。这看起来很有希望,但我担心我会在后期遇到问题。迟早我可能会尝试访问未完全获取的属性(错误)。我怎样才能实现我正在寻找的行为?

【问题讨论】:

  • 尼克,你可能是对的。我已经阅读了我之前的帖子并接受了最好的解决方案。感谢您的评论。

标签: iphone core-data


【解决方案1】:

您不应保留上下文已释放的托管对象。让上下文为您做到这一点。

问题是托管对象可以作为故障对象或已实现对象存在。当您保留一个时,您可能会保留不包含数据的故障。即使您确实保留了实际对象,该对象在与上下文分离后也可能无法正常运行。

为了处理您的场景,您需要 UI 的上下文,然后是服务器的上下文。在任一上下文进行更改后,您应该合并上下文以确保两者都相对于存储正确更新。

您的 UI 应该被配置为反映数据模型的状态,您不应该让数据模型的某些部分依赖于 UI 的状态。

【讨论】:

  • 我同意你的观点,但有一些后续问题。我没有保留 MO,但如果我在某处使用它,它可能会在我不知情的情况下被保留。可以向 NSArray 或 NSDictionary 添加 MO 吗?如果是这样,那么它将被保留......我是否需要合并上下文,或者我是否可以等待下一次从“读取”-上下文“获取?如果我合并两个,我担心我的数据会损坏我当前正在渲染的对象被删除的上下文(使用“write”-context)。
  • 我不清楚。我的意思是您不应该尝试保留上下文已处理的托管对象。那会变得一团糟。您应该合并上下文,但您需要在模型更新时冻结界面。看看 NSFetchedResultsController 在数据显示在表中时如何处理更新数据的确切问题。冻结 UI 通常完全不会被用户注意到。如果您有可能在用户使用它时被删除的数据,您需要重新考虑您的设计。用户应控制此类删除。
【解决方案2】:

我在我的数据库中遇到了同样的问题,因为我引用了不存在的对象(因为我将它与其他相关对象一起删除)。我的解决方案是在我的关系中设置“无操作”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 2014-02-09
    • 2011-08-01
    • 2013-05-02
    相关资源
    最近更新 更多