我正在使用web sockets和core-data构建一个聊天应用程序。
基本上,无论何时在web套接字上接收到消息,都会发生以下情况:
- 通过使用id(索引)执行核心数据获取来检查消息是否存在 如果1
- 。返回yes,更新消息并执行核心数据保存。如果1。 返回no,创建消息并执行核心数据保存。
- 通过更新或插入新行来更新表视图。
这是我的设置:
我有两个默认的管理对象上下文。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+),或者我可能会选择缓存高度自己(因为行不改变)或只是显示更少的行