2010-09-09 53 views
6

我想我理解错误消息:CoreData无法履行错误,但我不知道该如何处理它。当HTTP服务更新对象时,CoreData无法完成故障

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

  1. 从持久性存储中获取本地对象,并返回到UI
  2. 询问服务器如果对象被更新 - 当我得到的答案,我更新了核心数据管理对象
  3. 更新UI与更新的对象

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

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

我想我可以使用单独的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 = @"[email protected]"; 

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

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

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

NSFetchRequest *fetchRequest = [managedObjectModel fetchRequestFromTemplateWithName:@"authorByEmail" substitutionVariables:[NSDictionary dictionaryWithObject:@"[email protected]" 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进行提取,我会得到一个异常。这看起来很有前途,但恐怕我会在后期遇到问题。迟早我可能会尝试访问一个不完全提取的属性(一个错误)。我如何实现我正在寻找的行为?

+0

尼克,你可能是对的。我已阅读我以前的帖子并接受了最佳解决方案。谢谢你的评论。 – Andi 2010-09-10 06:11:52

回答

14

您不应该保留上下文已发布的托管对象。让上下文为你做。

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

为了处理您的情况,您需要UI的上下文,然后需要服务器的上下文。在任何上下文进行更改后,您应合并上下文以确保两者都相对于商店正确更新。

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

+1

我同意你的意见,但有一些跟进问题。我没有保留MO,但是如果我在某个地方使用它,可能会在我不知道的情况下保留它。添加MO到NSArray或NSDictionary可以吗?如果是这样,那么它将被保留... 我是否需要合并上下文,或者我可以等待下一次从“read”-context“中获取?我担心如果我的数据被损坏合并两个上下文,其中我当前正在渲染的对象被删除(使用“write”-context)。 – Andi 2010-09-13 18:56:41

+1

我还不清楚。我的意思是你不应该试图保留一个上下文已经处理的托管对象。这会变得混乱。您应该合并上下文,但您需要在模型更新时冻结界面。看看NSFetchedResultsController如何在数据显示在表中时更新数据来处理这个确切的问题。冻结用户界面通常完全不被用户察觉。如果您的数据在用户使用时可能会被删除,您需要重新考虑您的设计。用户应该控制这种删除。 – TechZen 2010-09-14 11:55:55

0

我在我的数据库中有同样的问题,因为我指的是不存在的对象(因为我用其他关系对象删除它)。我的解决方案是在我的关系中设置“无动作”。