iOS:SharedCoreData示例代码(iCloud + CoreData)|如何合并更改

时间:2012-10-25 15:43:18

标签: ios core-data icloud

我正在尝试为iCloud和CoreData(link to github sample code)采用WWDC 2012示例代码,并需要一些帮助来了解正在发生的事情。

我有一个表视图,它从NSFetchedResultsController获取其内容,就像在示例中一样。 NSFetchedResultsController与示例提供的CoreDataController中的主NSManagedObjectContext连接。对托管的更改从一个设备同步到另一个设备,它就像一个魅力。但是,没有地方可以将iCloud的更改实际合并到主要上下文中。我已经看到很多例子,其中NSPersistentStoreDidImportUbiquitousContentChangesNotification用于合并更改,但在此代码中从未发生过。

但这是奇怪的事情:我从主要上下文中获取一个对象并持有它。如果我收到NSPersistentStoreDidImportUbiquitousContentChangesNotification,我使用objectId并从NSMangedObjectContext重新加载对象:

NSManagedObjectID* objectId = [myObject objectID];
NSManagedObject* theNewObject = [[_coreDataController mainThreadContext] objectWithID:objectId];
myObject = theNewObject;

但该对象不是最新的。即使我使用对象的唯一属性对谓词进行提取。但是NSFetchedResultsController的表视图显示了更改。我在这里缺少什么?

编辑1(阅读汤姆的答案后):

我添加了NSPersistentStoreDidImportUbiquitousContentChangesNotification的观察者:

- (void)iCloudupdate:(NSNotification*)note {
    NSManagedObjectContext* moc = [[CoreDataController sharedController] mainThreadContext];
    [moc performBlock:^{
        [moc mergeChangesFromContextDidSaveNotification:note];
        [self refreshObject];
    }];
}

方法refreshObject使用NSManagedObjectID从主MOC获取对象,但它仍然是旧版本。

2 个答案:

答案 0 :(得分:4)

这可能是iOS错误。请参阅此主题:http://devforums.apple.com/message/735512#735512

这为我解决了这个问题:

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
moc.stalenessInterval = 0;

这没有帮助:

[moc refreshObject:myObject mergeChanges:YES];

答案 1 :(得分:1)

缺少NSPersistentStoreDidImportUbiquitousContentChangesNotification是Sha​​redCoreData示例代码中非常重要的遗漏。你肯定需要观察它,而你没有这样做的事实与没有看到更新的值直接相关。如果你要退出应用程序并重新启动它,你可能会得到你期望的新值。

在最简单的情况下,收到此通知时需要做两件事:

  1. 使用传入的更改通知作为参数调用-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]。这将通知您的MOC有关新值的信息。如果您有未保存的内存更改,它们将根据MOC的合并策略与传入的更改合并(有关这些选项的更多详细信息,请参阅NSMergePolicy文档中列出的常量)。
  2. 运行重复数据删除过程。示例代码 有一个示例实现。您需要查看它并查看它是否适合您的数据模型 - 即它是否实际检测到重复项。