Cocoa touch UITableView InsertRowsatindExpath导致应用程序无响应

Cocoa touch UITableView InsertRowsatindExpath导致应用程序无响应,cocoa-touch,ios,Cocoa Touch,Ios,我有一个表视图,它是从获取的结果控制器填充的。我还使用NSTimer每分钟进行一次API调用,以获取要显示的任何新数据。使用GCD和新的托管对象上下文异步执行此操作,并在完成时使用mergeChangesFromContextDidSaveNotification将中的更改合并到主托管对象上下文。这将触发获取的结果控制器委托方法,并使用InsertRowsatindExpath将任何新行插入表中 这一切都按预期进行,但是我看到在调用UITableView endUpdates和新单元格出现在表视

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

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

我有点困惑从哪里开始调试这个问题-单元配置都发生在endUpdates调用之前,而且似乎不需要很长时间

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

编辑

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

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

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

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

您现在可能已经自己解决了这个问题,但我今天遇到了同样的问题,我认为需要为后代解答

最可能发生的情况是,您已在主线程上设置了
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
      }
  });
});

到现在为止,你可能已经自己解决了这个问题,但我今天遇到了这个问题,当时我确实遇到了同样的问题,并且认为它需要为子孙后代解答

最可能发生的情况是,您已在主线程上设置了
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
      }
  });
});

是的,我在每一步都添加了日志,一切都发生得很快。我将使用日志摘要更新原始问题。尝试使用时间分析器通过仪器运行应用程序,并检查将显示的峰值。仪器在挂起期间未显示任何峰值。我使用的是自定义单元格,但不是UITableViewCell的子类-它们是在出列单元格为nil时设置的。插入新单元格时,不会执行内存分配—只会更新创建单元格时设置的标签和imageview。如果没有意义,我可以发布代码。@barrym你的cells子类是什么?合并更改时,insertRowsAtIndexPaths是自动调用的还是您调用的?很抱歉延迟-我想我已经将范围缩小到了mergeChangesFromContextDidSaveNotification,insertRowsAtIndexPaths看起来是在转移视线。我仍然不完全清楚实际的问题是什么,但仍在努力解决。是的,我在每一步都添加了日志,一切都很快发生。我将使用日志摘要更新原始问题。尝试使用时间分析器通过仪器运行应用程序,并检查将显示的峰值。仪器在挂起期间未显示任何峰值。我使用的是自定义单元格,但不是UITableViewCell的子类-它们是在出列单元格为nil时设置的。插入新单元格时,不会执行内存分配—只会更新创建单元格时设置的标签和imageview。如果没有意义,我可以发布代码。@barrym你的cells子类是什么?合并更改时,insertRowsAtIndexPaths是自动调用的还是您调用的?很抱歉延迟-我想我已经将范围缩小到了mergeChangesFromContextDidSaveNotification,insertRowsAtIndexPaths看起来是在转移视线。我仍然不完全清楚实际的问题是什么,但仍在努力解决。是的,这肯定需要为子孙后代解答,因为我也遇到过这种确切的行为,可能会花费数小时(在我已有的基础上)翻阅文档并随机尝试,直到成功。是的,这肯定需要为子孙后代解答,因为我也遇到过这种确切的行为,可能会花费数小时(在我已有的基础上)翻阅文档并随机尝试,直到成功。