带有 UIDocument 的核心数据:新对象的关系在 didEnterBackground 和重新打开后被破坏

Posted

技术标签:

【中文标题】带有 UIDocument 的核心数据:新对象的关系在 didEnterBackground 和重新打开后被破坏【英文标题】:Core Data with UIDocument: RelationShips of new Objects somwhow broken after didEnterBackground and reopen 【发布时间】:2012-03-14 09:08:01 【问题描述】:

我将我的应用程序从在应用程序委托中管理 sqlite 存储的单个上下文更改为 UIManagedDocument(就像激活了 Core Data 的默认 Xcode 模板)。 现在,在我关闭(后台)并重新打开应用程序之后,尝试获取自当前应用程序启动以来创建的对象时,我遇到了一些奇怪的行为。

有 2 个实体:文件夹和项目。 文件夹到项目是一对多的关系。

我的 fetchedResultsController 的谓词显示当前文件夹中的项目如下所示:

[fetchRequest setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(folder == %@)", self.currentFolder]];    

除了一种情况外,这仍然可以正常工作: - 我创建一个新文件夹,向其中添加一些项目 - 然后关闭(后台)并重新打开应用程序 - 选择要在 TableView 中显示的文件夹 然后 fetch 返回 0 个结果。

只要我终止应用并重新打开它,文件夹的项目就会再次显示(并且 fetchRequests 返回正确的项目数量)。

我在 viewDidAppear 内部做了一些进一步的测试,使用了一些没有 fetchedResultsController 的手动 fetchRequests。 而且我真的不明白这怎么会发生。

两个 fetchRequest 基本相同(也与 fetchedResultController 相同), 但第一个没有谓词,然后在 for 循环中检查项目的文件夹是否是 viewController 的 currentFolder。

据我了解,这应该会导致完全相同的行为,但是虽然谓词在后台运行后失败, 在 for 循环中获取所有项目 + 测试一直都可以正常工作。

// Returns fetchResult.count = 0 for new created folders after backgrounding the app 
[fetchRequest1 setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest1 setPredicate:[NSPredicate predicateWithFormat:@"(folder == %@)", self.currentFolder]];
NSArray *fetchResult1 = [self.context executeFetchRequest:fetchRequest1 error:nil];

// This time get all items in the context withour predicate
[fetchRequest2 setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context]];
[fetchRequest2 setPredicate:nil];
NSArray *fetchResult2 = [self.context executeFetchRequest:fetchRequest1 error:nil];

// Filter to get only the items in the current folder
NSMutableArray *filteredFetchResults2 = [NSMutableArray mutableArrayWithCapacity:0];
for (Item *item in fetchResult2) 
    if (item.folder == self.currentFolder) [filteredFetchResults2 addObject:item];

// filteredFetchResults2 holds the correct items even after backgrounding. Why?!?

怎么可能?

【问题讨论】:

什么是self.context?您如何“保存”文档? 【参考方案1】:

我想答案是这样的,因为后台只会保存文件: Core Data managed object does not see related objects until restart Simulator

经验教训:暂时最好避免使用 UIManagedDocument。即使您想在没有 iCloud 的情况下在本地使用它。

【讨论】:

以上是关于带有 UIDocument 的核心数据:新对象的关系在 didEnterBackground 和重新打开后被破坏的主要内容,如果未能解决你的问题,请参考以下文章

带有自动保存功能的 UIDocument 何时保存文件

数据持久化方案解析(八) —— UIDocument的数据存储(一)

在 NSDocument 和 UIDocument 之间共享代码

带有核心数据的 Cocoa 绑定不更新所有列

IOS 5 UIDocument 子类向后兼容吗?

iPhone4 Core Data如何插入带有节号的新对象?