CoreData无法解决HTTP服务更新对象的错误

时间:2010-09-09 22:06:39

标签: iphone core-data

我想我理解错误信息:CoreData无法解决问题,但我不确定应该如何处理它。

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

  1. 从持久存储中获取本地对象并返回到UI
  2. 询问服务器是否更新了对象 - 当我得到答案时,我更新了核心数据管理对象
  3. 使用更新的对象更新UI
  4. 问题是;即使我不使用多线程,当HTTP请求删除我的UI保留的托管对象时,我有时会收到错误。我试图用returnsObjectsAsFaults获取对象为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进行提取,我会得到一个例外。这看起来很有希望,但我担心我会在以后遇到问题。迟早我可能会尝试访问一个未完全取出的属性(故障)。我怎样才能实现我正在寻找的行为?

2 个答案:

答案 0 :(得分:14)

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

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

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

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

答案 1 :(得分:0)

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