1

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

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

一切正常,但当 Document 填充数据时 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];
}];
4

3 回答 3

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
    }];
}];

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

于 2012-05-18T22:26:34.120 回答
0

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

[self.tableView reloadData];

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

希望对您有所帮助……</p>

于 2012-05-18T21:42:36.733 回答
0

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

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

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

于 2012-05-20T14:06:44.317 回答