为什么NSTableView会在滚动时重绘每个单元格?

时间:2013-11-13 19:32:07

标签: macos cocoa scroll nstableview

我有一个包含5列的NSTableView,每列包含笔尖中的NSTableCellView。 (库存单元格有一个文本框和一个可选图像。)填充后,表格大约有50行。一切都很好,但滚动表现非常糟糕。看起来这种情况正在发生,因为每当表格滚动时,每个单元格都会获得一个drawRect:消息,表示其完整的rect。但是,reloadData和reloadDataForRowIndexes:ColumnIndexes:都没有被调用,所以不是这样。它也不是单元格的内容:我试着将我的所有代码都注释掉,只留下每个单元格的默认单元格图像和文本,性能也是一样的。滚动时,没有任何单元格更新。 (我在tableView中设置了一个断点:viewForTableColumn:row:以确保。)

我的实现具有以下委托方法:

  • tableView:viewForTableColumn:row:在委托中;这将通过makeViewWithIdentifier:owner:
  • 创建并填充新单元格
  • numberOfRowsInTableView:在数据源中;这将返回一个常数
  • tableView:sortDescriptorsDidChange:在数据源中

就是这样!不是很复杂,但是。

我觉得我错过了一些完全明显的东西。什么可能导致这些重绘?


编辑:想想看,其他几个应用程序(uTorrent,Xcode)似乎表现出相同的慢滚动行为。如果你在滚动时查看CPU使用情况,你真的可以看到它。另一方面,活动监视器具有黄油般平滑的滚动功能,根本不会对CPU造成任何影响。我如何在我的应用程序中获得它?


编辑2:我想我发现了自己的错误。 According to Apple

  

在iOS应用中,始终启用Core Animation并支持每个视图   一层。在OS X中,应用必须明确启用Core Animation   通过执行以下操作获得支持:

     
      
  • 与QuartzCore框架的链接。 (iOS应用必须仅在明确使用Core Animation接口时才链接此框架。)
  •   
  • 通过执行以下操作之一,为一个或多个NSView对象启用图层支持:

         
        
    • 在您的nib文件中,使用View Effects检查器为您的视图启用图层支持。检查员显示复选框   选定的视图及其子视图。建议您启用   尽可能在窗口的内容视图中支持图层。
    •   
    • 对于以编程方式创建的视图,调用视图的setWantsLayer:方法并传递值YES以指示   视图应该使用图层。
    •   
  •   
     

以上述方式之一启用图层支持会创建一个   图层支持的视图。使用图层支持的视图,系统需要   负责创建底层图层对象和   保持该层更新。在OS X中,还可以创建一个   图层托管视图,您的应用实际上创建和管理   底层图层对象。 (您无法在中创建图层托管视图   iOS。)有关如何创建图层托管视图的更多信息,请参阅   “图层托管允许您更改OS X中的图层对象。”

我会在解决性能问题后立即添加答案。通过粗略的传递,我的滚动仍然是颠簸,但滚动时我的CPU使用率从70%下降到10%。

1 个答案:

答案 0 :(得分:1)

对于记录...... OP的编辑2使世界变得不同。

  

在iOS应用中,始终启用Core Animation并支持每个视图   一层。在OS X中,应用必须明确启用Core Animation   通过执行以下操作获得支持:

     

与QuartzCore框架的链接。 (iOS应用必须链接   这个框架只有在他们明确使用Core Animation接口的时候。)   通过执行为一个或多个NSView对象启用图层支持   以下之一:

     

在您的nib文件中,使用View Effects检查器启用图层   支持您的观点。检查员显示的复选框   选定的视图及其子视图。建议您启用   尽可能在窗口的内容视图中支持图层。   对于以编程方式创建的视图,请调用视图的setWantsLayer:   方法并传递值YES以指示视图应使用   层。以上述方式之一启用层支持会创建一个   图层支持的视图。使用图层支持的视图,系统需要   负责创建底层图层对象和   保持该层更新。在OS X中,还可以创建一个   图层托管视图,您的应用实际上创建和管理   底层图层对象。 (您无法在中创建图层托管视图   iOS。)有关如何创建图层托管视图的更多信息,请参阅   “图层托管允许您更改OS X中的图层对象。”