我正在尝试为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获取对象,但它仍然是旧版本。
答案 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
是SharedCoreData示例代码中非常重要的遗漏。你肯定需要观察它,而你没有这样做的事实与没有看到更新的值直接相关。如果你要退出应用程序并重新启动它,你可能会得到你期望的新值。
在最简单的情况下,收到此通知时需要做两件事:
-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]
。这将通知您的MOC有关新值的信息。如果您有未保存的内存更改,它们将根据MOC的合并策略与传入的更改合并(有关这些选项的更多详细信息,请参阅NSMergePolicy
文档中列出的常量)。