NSFetchedResultsController插入锁定UI

时间:2014-07-14 17:02:53

标签: performance uitableview core-data nsfetchedresultscontroller

我正在使用网络套接字和核心数据构建聊天应用程序。

基本上,只要在Web套接字上收到消息,就会发生以下情况:

  1. 通过使用id(索引)
  2. 执行核心数据提取来检查消息是否存在
  3. 如果1.返回yes,则更新消息并执行核心数据保存。如果1.返回no,则创建消息并执行核心数据保存。
  4. 通过更新或插入新行来更新表格视图。
  5. 以下是我的设置:

    我有2个默认的托管对象上下文。 MAIN(NSMainQueueConcurrencyType)和WRITER(NSPrivateQueueConcurrencyType)。 WRITER引用了持久存储协调器,MAIN没有引用,但是WRITER被设置为MAIN的父代。

    TableView连接到NSResultsFetchController,连接到MAIN。

    Fetches全部使用MAIN作为其父级的临时上下文(“performBlock:”)执行。写入如下所示:保存临时上下文,然后保存MAIN,然后保存WRITER。

    问题:

    由于更新是通过网络套接字进入的,因此在繁忙的聊天室中,很多更新都会在短时间内发生。同步以获取较旧的消息可能意味着许多消息快速进入。这会锁定用户界面。

    我使用fetched-results-controller的委托跟踪对ui的更改,如下所示:

    // called on main thread
    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    {
      NSLog(@"WILL CHANGE CONTENT");
      [_tableView beginUpdates];
    }
    
    // called on main thread
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    {
      NSLog(@"DID CHANGE CONTENT");
      [_tableView endUpdates];
    }
    

    这是我在日志文件中看到的一个例子:

    2014-07-14 18:46:20.630 AppName[4938:60b] DID CHANGE CONTENT
    2014-07-14 18:46:22.334 AppName[4938:60b] WILL CHANGE CONTENT
    

    每次插入几乎是2秒!

    这只是我在这里用tableviews打的限制吗? (在某些情况下,我说的是1000多行)但我无法想象这种情况。 UITableViews针对这种操作进行了超级优化。

    我可能会提出任何明显的新手错误吗?

2 个答案:

答案 0 :(得分:0)

这不符合逻辑:

  

写入如下:保存临时上下文,然后保存MAIN,然后保存WRITER。

如果writer是main的子上下文,则在 next 保存之前不会保留更改。

答案 1 :(得分:0)

好的我明白了。

问题是tableView:heightForRowAtIndexPath:。计算行的高度的提取需要时间,每次调用tableView.endUpdates时,UITableView都需要所有行的高度。

tableView:estimatedHeightForRowAtIndexPath:是一种可行的方法(iOS7 +),或者我可能会选择自己缓存高度(因为行不会更改)或只显示更少的行altog