NSFetchedResultsController inserts lock up the UI



我正在使用web sockets和core-data构建一个聊天应用程序。

基本上,无论何时在web套接字上接收到消息,都会发生以下情况:

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

这是我的设置:

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

TableView连接到NSResultsFetchController,连接到MAIN。

读取都是使用以MAIN为父上下文的临时上下文("performBlock:")执行的。写操作如下:保存临时上下文,然后保存MAIN,然后保存WRITER。

问题:

因为更新是通过web套接字进入的,在一个繁忙的聊天室里,许多更新在短时间内发生。同步获取较旧的消息可能意味着许多消息会迅速传入。这就锁定了UI

我使用fetchedresultscontroller的委托来跟踪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秒!

这仅仅是我在tableview中碰到的限制吗?(我说的是在某些情况下超过1000行)但我无法想象这种情况。uitableview对这种操作进行了超级优化。

我可能会犯什么明显的新手错误?

这不符合逻辑:

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

如果writer是main的子上下文,则更改不会被持久化,直到下一个保存。

我明白了。

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

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

最新更新