NSTableView unhideRowsAtIndexes crashes

Deadly 提交于 2019-12-23 05:45:12

问题


I am creating a grouped NSTableView that loads just fine and with all my objects the way I want to.

I also created the possibility to collapse entire group sections (the rows between group rows) and I use the hideRowsAtIndexes:withAnimation: and unhideRowsAtIndexes:withAnimation: that were added to NSTableView ( https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/#10_11TableView).

Hiding always seem to work, but unhiding crashes for some rows. The last row hides and unhides just fine, the before last always crashes on unhiding. This behaviour is only happening when I have more rows then possible to be displayed.

The console crash log given by Xcode:

0   CoreFoundation                      0x00007fff95d034f2 __exceptionPreprocess + 178
1   libobjc.A.dylib                     0x00007fff9b506f7e objc_exception_throw + 48
2   CoreFoundation                      0x00007fff95c1a7c5 -[__NSArrayM objectAtIndex:] + 245
3   AppKit                              0x00007fff94e0496c -[NSTableRowData _updateVisibleViewsBasedOnUpdateItems] + 2701
4   AppKit                              0x00007fff94e03dc5 -[NSTableRowData _updateVisibleViewsBasedOnUpdateItemsAnimated] + 241
5   AppKit                              0x00007fff94d17d3f -[NSTableRowData _doWorkAfterEndUpdates] + 82
6   AppKit                              0x00007fff94d1db49 -[NSTableView _doUpdatedWorkWithHandler:] + 251
7   AppKit                              0x00007fff953209bc -[NSTableView hideRowsAtIndexes:withAnimation:] + 249
8   Testing NSTableView Collapse        0x0000000100004dfd -[AppDelegate collapse:] + 285
9   libsystem_trace.dylib               0x00007fff945ac07a _os_activity_initiate + 75
10  AppKit                              0x00007fff94e75dbd -[NSApplication sendAction:to:from:] + 460
11  AppKit                              0x00007fff94e87f12 -[NSControl sendAction:to:] + 86
12  AppKit                              0x00007fff94e87e3c __26-[NSCell _sendActionFrom:]_block_invoke + 131
13  libsystem_trace.dylib               0x00007fff945ac07a _os_activity_initiate + 75
14  AppKit                              0x00007fff94e87d99 -[NSCell _sendActionFrom:] + 144
15  libsystem_trace.dylib               0x00007fff945ac07a _os_activity_initiate + 75
16  AppKit                              0x00007fff94e863be -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2693
17  AppKit                              0x00007fff94ecef04 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 744
18  AppKit                              0x00007fff94e84ae8 -[NSControl mouseDown:] + 669
19  AppKit                              0x00007fff953d93c9 -[NSWindow _handleMouseDownEvent:isDelayedEvent:] + 6322
20  AppKit                              0x00007fff953da3ad -[NSWindow _reallySendEvent:isDelayedEvent:] + 212
21  AppKit                              0x00007fff94e19539 -[NSWindow sendEvent:] + 517
22  AppKit                              0x00007fff94d99a38 -[NSApplication sendEvent:] + 2540
23  AppKit                              0x00007fff94c00df2 -[NSApplication run] + 796
24  AppKit                              0x00007fff94bca368 NSApplicationMain + 1176
25  Testing NSTableView Collapse        0x0000000100001352 main + 34
26  libdyld.dylib                       0x00007fff89d675ad start + 1

Is there a possible fix or is this a framework problem?

CODE: http://pastebin.com/esMH1LBF


回答1:


As this problem has been plaguing me as well, I did some digging, and what do you know? You were right! It's an AppKit bug. Here are some details from AppKit's 10.13 Release Notes:

NSTableView

Hiding rows with the method -hideRowsAtIndexes:withAnimation: did not work correctly prior to macOS 10.13 when using standard row heights. This has been fixed for all applications on macOS 10.13. If you are targeting an older OS, it is recommended to use "variable row heights" by implementing -tableView:heightOfRow: and returning the desired row height; this will work around the bug with hidden row indexes.

Unhiding rows with the method -unhideRowsAtIndexes:withAnimation: did not work correctly prior to macOS 10.13 when using non-contiguous sets of rows. This has been fixed for all applications on macOS 10.13.

You’ll notice in the second paragraph that your issue is mentioned.

If you’re developing for an earlier version of macOS, you can do the following:

func unhideRows(at indexes: IndexSet, animation: NSTableView.AnimationOptions = []) {
    if #available(macOS 10.13, *) {
        outlineView.unhideRows(
            at: indexes,
            withAnimation: animation
        )
    } else {
        for range in indexes.rangeView {
            outlineView.unhideRows(
                at: IndexSet(integersIn: range),
                withAnimation: animation
            )
        }
    }
}

I wish I could say that this fixes the problem 100% of the time, however, that doesn't seem to be the case. Every once in awhile, I still seem to run into bounds exceptions like this:

-[__NSArrayM objectAtIndex:]: index 11 beyond bounds [0 .. 10]

This could be due to other factors, such as my semi-complex filtering code, but as I can’t actually see what Apple’s doing in its NSTableView methods like _updateVisibleViewsBasedOnUpdateItems, I’m just not sure.

Oh, well. I thought I should post an answer so other folks struggling with this issue are aware of the bug. Good luck and safe travels, my fellow earthling.



来源:https://stackoverflow.com/questions/37616958/nstableview-unhiderowsatindexes-crashes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!