问题
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