【问题标题】:Loading CoreData in a background thread在后台线程中加载 CoreData
【发布时间】:2012-05-18 21:12:48
【问题描述】:

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

【问题讨论】:

    标签: ios core-data


    【解决方案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
        }];
    }];
    

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

    【讨论】:

      【解决方案2】:

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

      [self.tableView reloadData];
      

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

      希望能有所帮助……

      【讨论】:

      • 顺便说一下,据我所知,NSFetchedResultsController 会监听来自 Core Data 的通知,但不确定是否来自每个…
      • 谢谢,但在尝试了您和 Jody 的建议并没有发现任何变化后,我决定检查文档,结果当我在屏幕上看到重复条目时,文档中确实存在重复条目。所以这是一个核心数据问题,而不仅仅是一个 UI 故障。
      • 这几乎就像 [backgroundContext save] 有时会添加到父上下文中的 Document 而不是出于某种原因替换它。保存从不报告错误。该文档是我之前在控制器中创建的 UIManagedDocument。
      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 2018-06-12
        • 1970-01-01
        相关资源
        最近更新 更多