【问题标题】:Writing and reading core data at the same time causing a UI freeze until writing is finished同时写入和读取核心数据导致 UI 冻结,直到写入完成
【发布时间】:2013-11-27 14:31:18
【问题描述】:

当我的应用程序启动时,它会将一组实体与服务器同步。 在此同步期间,它会更新核心数据中的实体并将其保存。 如果您打开应用程序(同步开始),然后我按下应该显示 tableView(带有 NSFetchedResultsController)的标签栏按钮,它会冻结片刻。

我真的不知道去哪里找问题。

更新一些额外的信息:

我正在使用一个主(父)上下文,用于获取 NSFetchedResultsController 和同步类中用于下载和保存更改的子上下文。

当所有更改完成后,我一个接一个地保存子上下文和父(主)上下文。 (我认为这是必要的。)。

【问题讨论】:

  • 你是在主线程上执行这个吗?如果是,则将其分派到后台线程,这样 UI 就不会冻结。
  • 与服务器的同步发生在后台线程上。我正在执行 fetch ,就像它在主线程的 viewDidLoad 中显示的那样:raywenderlich.com/999 我在不同的帖子/来源中读到应该在主线程上执行 fetch 操作。
  • 在后台队列中执行获取,仅在主线程中执行 UI 更新。

标签: ios objective-c core-data nsfetchedresultscontroller


【解决方案1】:

我从您的陈述中假设您的主上下文是这样创建的

let mainContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
    mainContext.persistentStoreCoordinator = CoreDatStack.sharedStack.persistentStoreCoordinator

您已经创建了如下的子上下文

let childContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType)
    childContext.parent = mainContext

冻结原因:您的 mainContext 保存操作在 MainThread 上执行(因为写入磁盘(持久存储)的过程很慢),因此阻塞主线程直到保存操作完成。

解决方案:在privateQueue上创建与PersistentStoreCoordinator链接的上下文,这样保存就不会在Main Queue上执行。

【讨论】:

    【解决方案2】:

    在 viewDidLoad 中添加如下内容:

    dispatch_queue_t jsonParsingQueue = dispatch_queue_create("jsonParsingQueue", NULL);
    
    // execute a task on that queue asynchronously
    dispatch_async(jsonParsingQueue, ^{
    
        //fetch code here
    
    
        // some code on a main thread (delegates, notifications, UI updates...)
        dispatch_async(dispatch_get_main_queue(), ^{
    
         //UI updates here
    
    
    
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多