带有 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的数据存储(一)