我正在为iPhone构建一个标签栏应用程序,而我正在使用Core Data
和两个UIManagedDocument
。在第一个选项卡中,我将数据写入数据库,在第二个选项卡中,我将其读入UITableView
UIFetchedResultsController
。
在应用程序开始时,如果我先写入数据,然后我读取结果,它就可以正常工作。结果立即显示在第二个选项卡中。但是,如果我首先读取一些数据,之后如果我向数据库写入内容,结果将显示在第二个选项卡中,相当长的延迟(差不多1分钟)。如果两个UIManagedObjectContext
或两个UIManagedDocument
之间存在任何同步问题,它在第一个条件下如何工作?而且,这种延迟有什么解决方案吗?
答案 0 :(得分:1)
确保您的UIManagedDocument是最新的方式是确保您正确保存更改。根据您上面显示的信息,我不确定您是如何管理文档或托管对象的。有太多因素可能影响到这一点,以便能够给出100%具体的答案。
因此,如果不知道您的代码是什么样的,并且不知道如何管理您的上下文,我唯一能做的就是为您提供我在自己的项目中使用的内容。这可能会或可能不会对您有所帮助,但在通过UIManagedDocument
处理核心数据时,它帮助了我 - 比一次更多 - 。
我使用单例来管理UIManagedDocument。我这样做是因为我不想处理你上面谈到的内容 - 拥有多个managedObjectContext。当您开始处理多个上下文时,除非您正确管理所有上下文,否则会遇到数据不一致的问题。如果您保存一个但不更新另一个 - 那么您的数据可能会变得不同步。您还必须确保每个上下文都在属性thread
上运行 - Apple Docs是一个很好的资源,可以帮助您理解这个甚至是重要的广告。
关键是,这是使用UIManagedDocument 的最大问题之一,并不像您使用纯核心数据和使用时一样糟糕SQL持久性存储。我找到的主要原因是因为UIManagedDocument实际上如何保存到其UIDocument商店。 想要保存时,这是非常难以预测的。这使得知道你的UIManagedDocument何时会实际存在,并让你的数据在黑暗中变得怪异。你必须做各种愚蠢的事情,以确保它总是随时可用。
考虑到我有一种信念(很多,也许这是理所当然的,相信是一种无知的信念),使用核心数据很难,而且UIManagedDocument使得它比你没有使用它更容易。所有。话虽这么说,当我处理像UIManagedDocument这样简单的事情开始变得复杂时,我不喜欢它 - 所以我使用了一件始终保持简单的东西,那就是单一的,单一的共享实例UIManagedDocument,以便我只有1个managedObjectContext,永远,必须使用。
每当我对模型进行任何重大更改(创建,更新,删除,编辑)时,我总是确保调用[document updateChangeCount:UIDocumentChangeDone];
我这样做因为我不使用"撤消经理" (NSUndoManager)使用UIManagedDocument时。仅仅因为我还没有必要,加上因为我讨厌所有"解决方法"垃圾与你有关。
每当我使用我的UIManagedDocument或Core Data执行任何时,我总是确保它在主线程上。我想我已经说了一次,但我会再说一遍:在你需要它时,在线程中工作是有帮助的,但是当你真正理解线程时也是如此。我喜欢在线程中工作,但它以复杂性为代价,这使得我不想在核心数据方面使用它们。在这种情况下,我倾向于严格遵守主线程,因为这样可以简单易用(对我来说)。
当我绝对需要确保UIManagedDocument被"保存" (写入磁盘),我有两种我编写和使用的方法,我随时可以拨打这些方法:saveDocument
和forceSaveDocument
。
第一个(saveDocument)仅检查上下文中的更改。如果有,则检查我们是否有任何新插入的对象。找到insertedObjects后,它将获取这些项的perm id。您可以将此视为确保核心数据模型是最新的,并且您的托管上下文处于安全状态的好方法,这样当您的文档实际保存时,您将获得所有内容< / em>保存在它需要进入的状态(你的id已经实现,你的上下文是干净的,你要保存的内容代表了你的模型在完成所有工作后的状态)。
它的大哥forceSaveDocument
实际上先调用saveDocument
。再次,确保您的实际模型/上下文得到保存和正确。如果它返回成功(YES),那么它实际上将通过saveToUrl
进行实际保存并将文档写入磁盘。
以下是这两种方法,如果它有帮助:
-(BOOL)saveDocument {
NSManagedObjectContext *context = self.document.managedObjectContext;
if(!context.hasChanges) return YES;
NSSet *inserts = [context insertedObjects];
if([inserts count] > 0) {
NSError *error = nil;
if(![context obtainPermanentIDsForObjects:[inserts allObjects] error:&error] && error) {
[self reportError:error];
return NO;
}
}
return YES;
}
-(void)forceSaveDocument {
if( [self saveDocument] ) {
[self.document saveToURL:self.document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:self.onSaveBlock ? self.onSaveBlock : nil];
}
}
总的来说,这些是我在使用UIManagedDocument和Core Data时遵循的指南(现在已经为我工作了大约3年)。我确信那些比我聪明的男人/女孩更好,但这些都有我用的东西。我从中获得的好处是,它让我不必担心少关于管理我的数据,并让我有更多的自由来处理其他事情:
UIManagedDocument
直到绝对需要多个线程 - 然后迁移开始使用多个上下文(我从来不需要这样做然而 - 但我又试着保持简单)updateChangeCount:UIDocumentChangeDone
。它重量很轻,影响很小。如果有的话,它将有助于确保您的文档保持最新,并且永远不会与您的数据太不同步。以上所有都是我自己的信念和理解。这些都来自于大量的研究,阅读,并且在想要做正确的事情时是一种痛苦,同时保持简单。任何人都可以编写复杂的解决方案 - 但我认为根本问题始终是:您是否真的需要复杂性,或者您是否只需要它来工作以便您可以专注于更复杂的问题?
我确信上述内容比您想要的更多,甚至可能会添加比您更多的问题。如果你需要一些链接和资源,请告诉我,我会尝试一些。
无论哪种方式,希望有所帮助。