Why can NSTableView redraw every cell when scrolling?

I have an NSTableView with 5 columns, each of which contains a stock of NSTableCellView in nib. (Stock cells have a text box and an additional image.) When populated, the table has about 50 rows. Everything looks fine, but the scroll performance is pretty poor. This seems to be happening because each cell receives a drawRect: message for its full rect whenever the table scrolls. However, neither reloadData nor reloadDataForRowIndexes: ColumnIndexes: is called, so this is not the case. This is not the contents of the cells: I tried to comment on all my code to just leave the default cell image and text for each cell, and the performance is the same. When scrolling, none of the cells is updated. (I set a breakpoint in tableView: viewForTableColumn: row: to make sure.)

My implementation has the following delegation methods:

  • tableView: viewForTableColumn: string: in the delegate; this creates and populates new cells through makeViewWithIdentifier: owner:
  • numberOfRowsInTableView: in the data source; it returns a constant number
  • tableView: sortDescriptorsDidChange: in data source

What is it! Not very difficult, though.

I feel like something is completely obvious to me. What can cause these redraws?


EDIT:. Think about it, some other applications (uTorrent, Xcode) seem to exhibit the same slow scroll behavior. You can really see this if you look at CPU usage while scrolling. Activity Monitor, on the other hand, has an oily, smooth scrolling that hardly touches the processor. How to get this in my application?


EDIT 2: I think I found my mistake. According to Apple :

In iOS applications, Core Animation is always turned on and supported by each view layer. In OS X, applications must explicitly enable Core Animation by following these steps:

  • Link to the QuartzCore structure. (iOS apps should reference this infrastructure only if they explicitly use Core Animation interfaces.)
  • Enable layer support for one or more NSView objects by doing one of the following:

    • In your nib files, use the View Effects Inspector to enable layer support for your views. The inspector displays check boxes for the selected view and its sub-items. It is recommended that you enable layer support in your window's content view whenever possible.
    • For the views you create programmatically, call the setWantsLayer: method and pass the value YES to indicate that the view should use layers.

Enabling layer support in one of the previous ways creates layer support. With a view with layer support, the system takes responsibility for creating the lower layer object and for updating this layer. In OS X, it is also possible to create that your application actually creates and manages a lower layer object. (You cannot create layer-level views in iOS.) For more information on how to create layer-level views, see "Layer Hosting allows you to change the layer object in OS X".

I will add an answer as soon as I fix my performance issues. With a quick skip, my scrolling is still bumpy, but my CPU usage has dropped from 70% to 10% when scrolling.

+6
source share
1 answer

For the record ... Edit 2 by OP makes a world of difference.

In iOS applications, Core Animation is always turned on and supported by each view layer. In OS X, applications must explicitly enable Core Animation by following these steps:

Link to the QuartzCore structure. (iOS applications should refer to this structure only if they explicitly use the Core Animation interfaces.) Enable layer support for one or more NSView objects by doing one of the following:

In your nib files, use the View Effects inspector to include a layer that supports your views. The inspector displays check boxes for the selected view and its sub-items. It is recommended that you enable layer support in your window's content view whenever possible. For the views you create programmatically, call the views of the setWantsLayer: method and pass the value YES to indicate that the view should use layers. Enabling layer support in one of the previous ways creates layer support. With a view with layer support, the system takes responsibility for creating the lower layer object and for updating this layer. In OS X, it is also possible to create that your application actually creates and manages a lower layer object. (You cannot create layer-level views in iOS.) For more information on how to create layer-level views, see "Layer Hosting allows you to change the layer object in OS X".

+1
source

Source: https://habr.com/ru/post/958023/


All Articles