NSTableView unhideRowsAtIndexes 崩溃

NSTableView unhideRowsAtIndexes crashes

我正在创建一个分组 NSTableView,它可以很好地加载,并且可以按照我想要的方式加载所有对象。

我还创建了折叠整个组部分(组行之间的行)的可能性,并且我使用添加到 NSTableViewhideRowsAtIndexes:withAnimation:unhideRowsAtIndexes:withAnimation:https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKit/#10_11TableView).

隐藏似乎总是有效,但取消隐藏某些行时会崩溃。最后一行隐藏和取消隐藏都很好,最后一行总是在取消隐藏时崩溃。只有当我有更多的行可以显示时才会发生这种行为。

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

是否有可能的修复方法或者这是一个框架问题?

代码: http://pastebin.com/esMH1LBF

由于这个问题也一直困扰着我,所以我做了一些挖掘,你知道什么?你是对的!这是一个 AppKit 错误。以下是 AppKit 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.

您会注意到在第二段中提到了您的问题。

如果您正在为早期版本的 macOS 开发,您可以执行以下操作:

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
            )
        }
    }
}

我希望我可以说这可以 100% 地解决问题,但是,情况似乎并非如此。每隔一段时间,我似乎仍然 运行 陷入这样的边界异常:

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

这可能是由于其他因素造成的,例如我的半复杂过滤代码,但由于我实际上看不到 Apple 在其 NSTableView 方法(如 _updateVisibleViewsBasedOnUpdateItems 中做了什么,我'我只是不确定。

哦,好吧。我想我应该 post 一个答案,这样其他正在为这个问题苦苦挣扎的人就会知道这个错误。祝你好运,一路平安,我的地球同胞。