在后台线程中加载核心数据



我觉得我今天已经阅读了Stack Overflow上的每一个CoreData问题,但仍然非常非常卡住。 :)

我正在开发一个使用 CoreData 的应用程序,该应用程序基于 Stanford University cs193p Lecture 14(Photomania 应用程序(中说明的方法。它使用实现 NSFetchedResultsController 委托的 UITableViewController 子类,当然,当获取结果时,表会自动更新。

一切正常,但当文档填充数据时,UI 会阻塞,因为它发生在主线程(即文档的 managedObjectContext(中。我已经在后台线程中下载数据,这只是实际填充导致阻塞的 NSManagedObject 的代码。该讲座暗示使用 NSManagedObjectContext 的父上下文在后台加载文档,然后在主线程中"重新获取"数据以填充表。我几乎有工作(我认为(,除了我经常在我的表格中得到双重条目。似乎[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];
}];

它仍在等待,因为你告诉它这样做。 使用 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
    }];
}];

当更改被推送到主上下文中时,获取的结果控制器将自动更新。

从您的代码中,我无法很好地看到问题可能真正出在哪里。你没有很清楚那个"文档"是什么,你正在加载。无论如何,什么可能会对您有所帮助:尝试在后台线程(您拥有的(中进行整个加载,发布通知以让表视图控制器了解更新,然后向控制器发送消息,例如:

[self.tableView reloadData];

那么你就不需要beginUpdates也不需要endUpdates,但是如果你找到一种方法需要使用它们(通常是NSFetchedResultsController的委托方法在-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller中使用它(,然后在更新数据之前和之后发送这些消息。

希望这有所帮助...

好吧,不知道为什么,但这解决了我的问题:https://stackoverflow.com/a/9451450/314051。具体来说,就在 [backgroundContext save] 之前:

NSSet *inserts = [backgroundContext insertedObjects]; 
[backgroundContext obtainPermanentIDsForObjects:[inserts allObjects] error:&error]; 

我需要做一些研究才能确切了解原因。感谢您的建议,这有助于我确定这不是 UI 问题。

最新更新