UITableView insertRowsAtIndexPaths导致应用无响应

时间:2011-05-22 14:12:12

标签: cocoa-touch ios

我有一个从获取的结果控制器填充的表视图。我也在使用NSTimer每分钟进行一次API调用,它会显示任何新数据。这是使用带有新托管对象上下文的GCD异步发生的,并使用mergeChangesFromContextDidSaveNotification在完成时将更改合并到主要托管对象上下文中。这将触发获取的结果控制器委托方法,并使用insertRowsAtIndexPaths将任何新行插入到表中。

这一切都按预期工作,但是我看到正在调用的UITableView endUpdates和表格视图中出现的新单元格之间有5秒的暂停。在此暂停期间,应用程序不响应任何触摸事件(标签栏,滚动表格视图等)。

我对从何处开始调试此问题感到困惑 - 单元格配置都发生在endUpdates调用之前,并且似乎没有花费很长时间。

代码相当复杂,但如果需要我可以发布。

编辑

这是一个日志摘录,显示从上下文合并到被调用的endUpdates的每次调用的时间:

2011-05-22 15:29:47.119 myapp[4136:7c1b] got background save notification
2011-05-22 15:29:47.124 myapp[4136:7c1b] controllerWillChangeContent
2011-05-22 15:29:47.128 myapp[4136:7c1b] NSFetchedResultsChangeInsert
2011-05-22 15:29:47.132 myapp[4136:7c1b] controllerDidChangeContent
2011-05-22 15:29:47.138 myapp[4136:7c1b] numberOfSectionsInTableView called
2011-05-22 15:29:47.140 myapp[4136:7c1b] numberOfSectionsInTableView called
2011-05-22 15:29:47.144 myapp[4136:7c1b] numberOfRowsInSection called
2011-05-22 15:29:47.157 myapp[4136:7c1b] cellForRowAtIndexPath called
2011-05-22 15:29:47.195 myapp[4136:7c1b] cellForRowAtIndexPath returning configured cell
2011-05-22 15:29:47.212 myapp[4136:7c1b] endUpdates called

2 个答案:

答案 0 :(得分:6)

你现在可能已经解决了这个问题,但是当我今天确实遇到完全相同的问题并认为需要回答子孙后,我遇到了这个问题。

最有可能发生的事情是您在主线程上设置了NSManagedObjectContext,然后在另一个线程上执行save,从而导致UITableView上的动画(这是在主线程上)等待该GCD线程被处理。

简单修复:执行所有计算密集型的东西以及在GCD线程中插入MOC,然后在主线程上执行save,如下所示:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{       
  // Do all your processing and inserting here

  // ... and then, when you're done:
  dispatch_async( dispatch_get_main_queue(), ^{
      NSError *anyError = nil;
      BOOL success = [self.managedObjectContext save:&anyError];
      if(!success) {
          // Error handling
      }
  });
});

答案 1 :(得分:0)

您是否检查了tableView:cellForRowAtIndexPath:完成所需的时间? 或者您的自定义tableview单元格中的“layoutSubviews”可能需要很长时间?