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

Posted

技术标签:

【中文标题】iOS:SharedCoreData 示例代码 (iCloud + CoreData) |如何合并更改【英文标题】:iOS: SharedCoreData Example Code (iCloud + CoreData) | How are changes merged 【发布时间】:2012-10-25 15:43:18 【问题描述】:

我正在尝试采用适用于 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 获取对象,但它仍然是旧版本。

【问题讨论】:

你能帮我解决这个问题吗? ***.com/questions/13718104/… 我不知道应该先做什么才能使用示例代码。我不能在我的应用程序中使用来自苹果的示例代码。我不是一个新手。我在 ios5 中做了同样的事情,即使用 iCloud 的核心数据。所以请帮帮我。谢谢。 我应该先对示例代码进行哪些更改? 【参考方案1】:

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

这为我解决了问题:

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

这没有帮助:

[moc refreshObject:myObject mergeChanges:YES];

【讨论】:

同时我可以解决你提到的问题,但仍然认为它感觉不对。但是这是一个解决方案,所以我将其标记为答案! 我在小牛队也遇到了同样的问题。因此,此问题不仅限于 iOS。将 stalenessInterval 设置为 0 解决了这个问题。非常感谢!【参考方案2】:

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

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

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

【讨论】:

感谢您的回答!文档说方法 mergeChangesFromContextDidSaveNotification 应该与 NSManagedObjectContextDidSaveNotification 一起使用。我尝试了您建议的其他“超长通知”,没有错误。所以我想你是对的。但是通过它的 objectId 从 MOC 获取对象仍然给我旧版本:(

以上是关于iOS:SharedCoreData 示例代码 (iCloud + CoreData) |如何合并更改的主要内容,如果未能解决你的问题,请参考以下文章

iOS/MacOS - iCloud 警告 - 以 SharedCoreData 为基础的普遍性错误

iOS中的ADSR,示例代码?

iOS开发数据库篇—SQL代码应用示例

c++ OpenCV 示例到 iOS 代码和 UIImage

iOS手机示例短信代码-短信API

正确移除对象(附代码示例) iOS