在后台线程中加载CoreData

时间:2012-05-18 21:12:48

标签: ios core-data

我觉得我今天已经阅读了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];
}];

3 个答案:

答案 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]; 

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