4

我正在尝试采用 iCloud 和 CoreData 的 WWDC 2012 示例代码(链接到 github 示例代码),并且需要一些帮助来理解那里发生的事情。

我有一个表格视图,它从 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 获取对象,但它仍然是旧版本。

4

2 回答 2

4

这可能是一个 iOS 错误。看到这个线程:http ://devforums.apple.com/message/735512#735512

这为我修复了它:

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

这没有帮助:

[moc refreshObject:myObject mergeChanges:YES];
于 2012-11-20T06:29:59.903 回答
1

SharedCoreData 示例代码的缺失NSPersistentStoreDidImportUbiquitousContentChangesNotification是一个相当大的遗漏。您肯定需要观察它,而您不这样做的事实与看不到更新的值直接相关。如果您要退出应用程序并重新启动它,您可能会得到您期望的新值。

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

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