保持CoreData NSManagedObject新鲜

时间:2014-01-18 19:47:44

标签: ios core-data nsmanagedobject nsmanagedobjectcontext magicalrecord

想象一下像Instagram这样的社交照片应用。您可以在Feed中看到朋友的一张照片。这张照片在CoreData中保存为:

Photo (NSManagedObject)
 Attributes: id, imageURL
 Relationships: comments (set of Comment objects), likes (set of Like objects)

我有一个视图控制器,它具有对Photo对象的引用。此视图控制器还处理喜欢和评论照片的操作。

因此,当有人喜欢照片时,流程就是这样:将相似内容发送到服务器。如果API帖子成功,请使用从服务器收到的任何新信息更新CoreData中的Photo对象,其中包括新的信息。此时,Photo在CoreData中应该有一个与之相关的Like对象,而不是在我按下like按钮之前。

现在我在这里遇到问题。视图控制器需要更新照片上的喜欢数量。在成功的方面,我这样做:

  self.likesLabel.text = [NSString stringWithFormat:@"%d likes", self.photo.likes.count];

问题是self.photo.likes.count此时报告0(在按下“喜欢”按钮之前它不为零)。如果我在其他地方导航并返回此屏幕,则计数将正确更新。因此,当我更新它时,Photo managedObject似乎变得“脏”。更新可能发生在另一个上下文中(我使用魔法记录)。更新看起来像这样:

NSManagedObjectContext* context = [NSManagedObjectContext MR_contextForCurrentThread];
Photo* photo = [Photo MR_findFirstWithPredicate:somePredicate inContext:context];
...
photo.likes = likes;
photo.comments = comments;
[photo save:context];

所以问题是,如何在视图控制器中正确保持Photo对象的更新,以便我可以始终可靠地查询喜欢和评论的数量?一般来说,如果可以在其他线程/上下文中更新NSMangagedObject,如何保持NSMangagedObject的最新版本呢?

我已经尝试过侦听NSManagedObjectContextObjectsDidChangeNotification,但是当我收到通知时,我遇到了Photo报告0喜欢和评论的相同问题。

2 个答案:

答案 0 :(得分:1)

我经常使用的这种情况的一个解决方案是KVO。在您的情况下,我会观察托管对象上的“likes”属性。您可以查看有关如何正确执行此操作的标准KVO文章。然而,这只是故事的一半。因此,为了正确地更改这些值,“管理”该属性需要自动更新的NSManagedObjectContext。这是在线程隔离上下文的情况下合并保存NSManagedOjbectContextDidSaveNotification事件或者父/子合并规则发挥作用的地方。关键是,您可以在应用程序中的任何上下文中更改实际数据。您可以将这些更改合并到您当前关注的上下文中(可能是屏幕上显示的内容)。

所有这一切,MagicalRecord应该有一些方法可以为你处理这个问题的一半。如果没有,请确保在保存背景上下文时正确更新显示使用信息的上下文。要记住的是你必须更新上下文,一旦上下文在更新中的新更改中合并,那么你的KVO方法将使用正确的值触发。

答案 1 :(得分:1)

监听并应用在其他环境中进行的合并

#pragma mark - Core Data stack

- (void)mergeChanges:(NSNotification *)notification {
    // Merge changes into the main context on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
        [[NSNotificationCenter defaultCenter] postNotificationName:MyMainContextMergedChangesNotification object:nil];
    });
}
合并后

可以刷新GUI


可选地/另外你可以强制上下文从db调用refreshObject:

的数据库中刷新对象