重新加载NSOutlineView经常导致崩溃

时间:2013-02-18 10:20:16

标签: macos cocoa nsoutlineview

在我的应用程序中,我想在mac中搜索文件,如果我有文件,我需要用该文件重新加载NSOutlineView。如果我经常重新加载NSOutlineView中的项目,则会导致崩溃。

//像这样我正在调用搜索文件的方法。

[self performSelectorInBackground:@selector(searchFiles) withObject:self];

//重新加载outlineview

  - (void)searchFiles {
    -------------------------
    -------------------------
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:filelistArray forKey:@"children"];
   [dictionary setObject:[NSString stringWithFormat:@"%ld",[filelist count]] forKey:@"parent"];
    [listArray addObject:dictionary];
    [outLineView reloadData];
}

//代表OutlineView

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {

    if ([item isKindOfClass:[NSDictionary class]])
        return YES;
    else
        return NO;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {

    if (item == nil)
        return [listArray count];

    if ([item isKindOfClass:[NSDictionary class]])
        return [[item objectForKey:@"children"] count];

    return 0;
}


- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {

    if (item == nil)
        return [listArray objectAtIndex:index];

    return [[item objectForKey:@"children"] objectAtIndex:index];

    return nil;
}


- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item {

    if ([item isKindOfClass:[NSDictionary class]])
        return [item objectForKey:@"parent"];
    else
        return item;
    return nil;
}

//崩溃日志

2013-02-18 15:44:13.800 OutLineViewReloadDemo[3054:303] *** Assertion failure in -[NSOutlineView _expandItemEntry:expandChildren:startLevel:], /SourceCache/AppKit/AppKit-1187.34/TableView.subproj/NSOutlineView.m:1309
2013-02-18 15:44:13.802 OutLineViewReloadDemo[3054:303] (null) should not be expanded already!
2013-02-18 15:44:13.806 OutLineViewReloadDemo[3054:303] (
    0   CoreFoundation                      0x00007fff81eef0a6 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff878a53f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff81eeeee8 +[NSException raise:format:arguments:] + 104
    3   Foundation                          0x00007fff8d4876a2 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 189
    4   AppKit                              0x00007fff83fcb9b0 -[NSOutlineView _expandItemEntry:expandChildren:startLevel:] + 1153
    5   AppKit                              0x00007fff83fb1c42 -[NSOutlineView _uncachedNumberOfRows] + 379
    6   AppKit                              0x00007fff83feb938 -[NSOutlineView frameOfCellAtColumn:row:] + 66
    7   AppKit                              0x00007fff83feb44f -[NSTableView drawRow:clipRect:] + 1636
    8   AppKit                              0x00007fff83fdb4c3 -[NSTableView drawRowIndexes:clipRect:] + 397
    9   AppKit                              0x00007fff83fdb321 -[NSOutlineView drawRowIndexes:clipRect:] + 113
    10  AppKit                              0x00007fff83fd9ea6 -[NSTableView drawRect:] + 1269
    11  AppKit                              0x00007fff83ebe144 -[NSView _drawRect:clip:] + 4217
    12  AppKit                              0x00007fff83ebc7a1 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1656
    13  AppKit                              0x00007fff83ebcbb9 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2704
    14  AppKit                              0x00007fff83ebcbb9 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2704
    15  AppKit                              0x00007fff83eba7d2 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 817
    16  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    17  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    18  AppKit                              0x00007fff83eba223 -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 314
    19  AppKit                              0x00007fff83eb5e4d -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4675
    20  AppKit                              0x00007fff83e7fd73 -[NSView displayIfNeeded] + 1830
    21  AppKit                              0x00007fff83e7f2ac _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 738
    22  Foundation                          0x00007fff8d4ee513 __NSFireTimer + 96
    23  CoreFoundation                      0x00007fff81eabda4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    24  CoreFoundation                      0x00007fff81eab8bd __CFRunLoopDoTimer + 557
    25  CoreFoundation                      0x00007fff81e91099 __CFRunLoopRun + 1513
    26  CoreFoundation                      0x00007fff81e906b2 CFRunLoopRunSpecific + 290
    27  HIToolbox                           0x00007fff8b28b0a4 RunCurrentEventLoopInMode + 209
    28  HIToolbox                           0x00007fff8b28ae42 ReceiveNextEventCommon + 356
    29  HIToolbox                           0x00007fff8b28acd3 BlockUntilNextEventMatchingListInMode + 62
    30  AppKit                              0x00007fff83e7c613 _DPSNextEvent + 685
    31  AppKit                              0x00007fff83e7bed2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
    32  AppKit                              0x00007fff83e73283 -[NSApplication run] + 517
    33  AppKit                              0x00007fff83e17cb6 NSApplicationMain + 869
    34  OutLineViewReloadDemo               0x0000000100001772 main + 34
    35  libdyld.dylib                       0x00007fff8206a7e1 start + 0
    36  ???                                 0x0000000000000003 0x0 + 3
)

我的问题是如何避免此次崩溃?

编辑1:

添加[outline reloadData]; in dispatch_async(dispatch_get_main_queue(),后,其工作完美,没有任何崩溃。但如果我扩展一些项目会导致崩溃。我无法弄清楚问题所在。这是我的崩溃日志。

*** Collection <__NSArrayM: 0x106536f70> was mutated while being enumerated.
0   CoreFoundation                      0x00007fff81eef0a6 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff878a53f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff81f82f98 __NSFastEnumerationMutationHandler + 232
    3   CoreFoundation                      0x00007fff81ec7281 -[NSArray containsObject:] + 177
    4   OutlineViewDemo                     0x000000010005ad60 -[MC_DuplicateFinderViewController outlineView:willDisplayCell:forTableColumn:item:] + 800
    5   AppKit                              0x00007fff83fed519 -[NSTableView preparedCellAtColumn:row:] + 1573
    6   AppKit                              0x00007fff83feccfc -[NSOutlineView preparedCellAtColumn:row:] + 56
    7   AppKit                              0x00007fff83fecc07 -[NSTableView _drawContentsAtRow:column:withCellFrame:] + 47
    8   AppKit                              0x00007fff83fecb7b -[NSOutlineView _drawContentsAtRow:column:withCellFrame:] + 94
    9   AppKit                              0x00007fff83feb63e -[NSTableView drawRow:clipRect:] + 2131
    10  AppKit                              0x00007fff83fdb4c3 -[NSTableView drawRowIndexes:clipRect:] + 397
    11  AppKit                              0x00007fff83fdb321 -[NSOutlineView drawRowIndexes:clipRect:] + 113
    12  AppKit                              0x00007fff83fd9ea6 -[NSTableView drawRect:] + 1269
    13  AppKit                              0x00007fff83ebe144 -[NSView _drawRect:clip:] + 4217
    14  AppKit                              0x00007fff83ebc7a1 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1656
    15  AppKit                              0x00007fff83ebcbb9 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2704
    16  AppKit                              0x00007fff83eba7d2 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 817
    17  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    18  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    19  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    20  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    21  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    22  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    23  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    24  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    25  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    26  AppKit                              0x00007fff83ebbb24 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5763
    27  AppKit                              0x00007fff83eba223 -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 314
    28  AppKit                              0x00007fff83eb5e4d -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4675
    29  AppKit                              0x00007fff83e7fd73 -[NSView displayIfNeeded] + 1830
    30  AppKit                              0x00007fff83e7f2ac _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 738
    31  AppKit                              0x00007fff8444a971 __83-[NSWindow _postWindowNeedsDisplayOrLayoutOrUpdateConstraintsUnlessPostingDisabled]_block_invoke_01208 + 46
    32  CoreFoundation                      0x00007fff81eb59b7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    33  CoreFoundation                      0x00007fff81eb5921 __CFRunLoopDoObservers + 369
    34  CoreFoundation                      0x00007fff81e90d88 __CFRunLoopRun + 728
    35  CoreFoundation                      0x00007fff81e906b2 CFRunLoopRunSpecific + 290
    36  HIToolbox                           0x00007fff8b28b0a4 RunCurrentEventLoopInMode + 209
    37  HIToolbox                           0x00007fff8b28ae42 ReceiveNextEventCommon + 356
    38  HIToolbox                           0x00007fff8b28acd3 BlockUntilNextEventMatchingListInMode + 62
    39  AppKit                              0x00007fff83e7c613 _DPSNextEvent + 685
    40  AppKit                              0x00007fff83e7bed2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
    41  AppKit                              0x00007fff83e73283 -[NSApplication run] + 517
    42  AppKit                              0x00007fff83e17cb6 NSApplicationMain + 869
    43  OutlineViewDemo                     0x0000000100001462 main + 34
    44  libdyld.dylib                       0x00007fff8206a7e1 start + 0
)

1 个答案:

答案 0 :(得分:2)

performSelectorInBackground:withObject:在新的后台线程上运行选择器,而UI上的更新(以及大多数其他操作)必须在主线程上执行。因此,崩溃,将是我的猜测。

从主线程获取控件更新的一种简单方法是使用Grand Central Dispatch(GCD),如下所示:

dispatch_async(dispatch_get_main_queue(), ^{
    [outLineView reloadData];
});