我觉得我今天已经阅读了Stack Overflow上的每个CoreData问题,而且我仍然非常困难。 :)
我正在开发一个使用CoreData的应用程序,该应用程序基于斯坦福大学cs193p第14讲(Photomania应用程序)中说明的方法。它使用UITableViewController子类来实现NSFetchedResultsController委托,当然,在获取结果时表会自动更新。
一切正常,但是当文档填充数据时,UI会阻塞,因为它发生在主线程(文档的managedObjectContext)中。我已经在后台线程中下载了数据,这只是实际填充导致阻塞的NSManagedObjects的代码。讲座暗示使用NSManagedObjectContext的Parent上下文以便在后台加载Document,然后“重新获取”主线程中的数据以填充表。我几乎有工作(我认为),除了我经常在我的表中获得双重条目。看起来像[self.tableView beginUpdates] / [self.tableView endUpdates]会解决这个问题,但因为我在后台上下文中执行NSManagedObjectContext保存,我不知道我会把它放在哪里。
我也可能以完全错误的方式解决这个问题。 :)无论如何,这是相关的代码:
NSManagedObjectContext *backgroundContext;
backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// document is my UIManagedDocument
backgroundContext.parentContext = document.managedObjectContext;
[backgroundContext performBlockAndWait:^{
// Do stuff here to populate the document.
[backgroundContext save:nil];
}];
答案 0 :(得分:1)
它还在等待,因为你告诉它这样做。使用performBlock,它可以在自己的线程上工作。
[backgroundContext preformBlock:^{
// Do your background stuff
[backgroundContext save:&error]; // handle the error
[document.managedObjectContext performBlock:^{
// Tell the document it has dirty data and should save
[document updateChangeCount:UIDocumentChangeDone];
// Do any UI-related stuff
}];
}];
当更改被推送到主上下文时,获取的结果控制器将自动更新。
答案 1 :(得分:0)
从你的代码中我看不出问题可能在哪里。您没有明确说明您正在加载的“文档”是什么。无论如何,有什么可以帮助你:尝试在后台线程(你有)中的整个加载,发布通知让表视图控制器知道更新,然后只是告诉控制器像:
[self.tableView reloadData];
然后您不需要beginUpdates
也不需要endUpdates
,但是如果您找到了一种方法,则需要使用它们(通常NSFetchedResultsController
的委托方法在-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
中使用它}和- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
),然后在更新数据之前和之后发送这些消息。
希望有所帮助...
答案 2 :(得分:0)
嗯,不知道为什么,但这解决了我的问题:https://stackoverflow.com/a/9451450/314051。具体来说,就在[backgroundContext save]之前:
NSSet *inserts = [backgroundContext insertedObjects];
[backgroundContext obtainPermanentIDsForObjects:[inserts allObjects] error:&error];
我需要做一些研究才能确切了解原因。感谢您的建议,这有助于我确定这不是一个用户界面问题。