基于NSTableview View的滚动性能

时间:2014-11-02 06:26:09

标签: macos cocoa swift scroll nstableview

我对 OS X Cocoa 编程相当新,但已经决定使用新的Swift语言。

我有一个NSTableView,有1500行(会更多)和7列。有一个复选框列,其余是文本字段,一个带有日期格式,另一个带有货币格式器。我首先将其设置为基于单元格。滚动是黄油光滑的(我甚至做了一个测试,增加了100万行,仍然很平滑)。这是在小牛队。

然后我升级到 Yosemite ,滚动性能显着下降。在表格视图上启用核心动画图层复选框改进了这一点,但仍然比在小牛队中更糟糕。

在我试图提高优胜美地的滚动表现时,我遇到了基于视觉的" NSTableViews。从文档中可以看出,基本上不应该使用基于单元格的表视图,只支持旧项目。

因此我将表格转换为基于视图的表格视图。样本简单概念,没什么复杂的。滚动表现绝对可怕。如果你滚得非常慢,它就足够平滑,但是一旦你开始滚动得更快,就像它没有足够的缓冲一样,它会开始出现口吃和抽搐。此外,当NSTableview被填充时,聚焦和散焦窗口需要花费一秒或更多时间(我再次在小牛队中尝试过这种情况并且不存在,滚动也有所改善,但仍然无法靠近基于细胞)。 / p>

基于视图的NSTableviews总是不利于滚动性能吗?如果是这样,为什么苹果建议在基于单元格NSTableviews的基础上使用它们。

此外,像safari和Reeder2这样的应用程序即使在约塞米蒂也有黄油平滑滚动。他们是如何实现这一目标的?

我是否遗漏了某些东西,或者OS X的性能是否会随着每件新事物而下地狱?即

  

小牛队>优胜美

     

基于细胞的>基于视图的

     

旧>新

非常感谢任何帮助。谢谢!

5 个答案:

答案 0 :(得分:4)

根据Apple的说法,OSX默认情况下从不启用QuartzCore(相反,做iOS)。所以,你需要:

  • 在Build Settings窗格下链接QuartzCore.framework您的项目。
  • 为您的主窗口启用CoreAnimation Layer(在IB上的View Effects Inspector下)(如果可能,否则请确保在容器视图上启用它,这会给您带来糟糕的性能)。

引用Apple文档:

  

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

     

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

     

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

更多信息:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/SettingUpLayerObjects/SettingUpLayerObjects.html

答案 1 :(得分:2)

我最近发现自己处于一种非常相似的情况,基于NSOutlineView的单元格在优胜美地之前快速燃烧,并且在升级到优胜美地后几乎停止了。

根据我的经验,在表格视图本身上启用图层支持是不够的,您还必须为包含表格视图的NSScrollView启用它,并且NSClipView

进行这些更改后,我的表格视图再次加速,但遇到了一些奇怪的视觉瑕疵。由于您没有使用在Yosemite中使用新的活力/透明度的源列表NSOutlineView,因此可能与您的情况相关或不相关。

在任何情况下,只要我转换为基于视图的表格,这些“效果”就会消失。

答案 2 :(得分:0)

最近他们引入了名为" Reuse queues"的概念,其中只有当前可见的行实际上在表中。从滚动中移出的行将被新引入的行替换。这是为了提高性能而引入的。但考虑到百万x 7个视图,我想在重用队列中可能会浪费很多CPU周期 与视图相比,细胞重量轻。


如果可能,您可以考虑将单个tableview重组为多个tableview。实际上,人类需要在他们的脑海中使用至少一些简单的谓词来查看数据。例如,您可能希望在组织中查看

  1. 所有经理详情
  2. 所有员工的薪水都大于x
  3. 所有女性员工
  4. 而不是一次查看所有员工的详细信息 因此,仅使用所需信息初始化表视图将增强性能和UX。

答案 3 :(得分:0)

我遇到了类似的问题。我也是Swift和Apple开发的新手。我的项目运行良好,直到我开始添加1000行或更多行。

经过一番游戏后,我将问题缩小到了我的基于字典的数据源的访问方式。这可能会指出你正确的方向。

 func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {...

 return myDictionary.values.array[row] //-- this makes access very slow, jerky with pauses

return myDictionary[someKey] //-- this makes access a lot faster, smooth and slick

看起来我的数据源需要一些重新工作。它仍然没有经过大量数据的测试,但一开始似乎有显着差异。

答案 4 :(得分:0)

您只需关闭"绘制背景"在文本单元格(或组单元格)上

enter image description here