在我的应用程序中,我想在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
)
答案 0 :(得分:2)
performSelectorInBackground:withObject:
在新的后台线程上运行选择器,而UI上的更新(以及大多数其他操作)必须在主线程上执行。因此,崩溃,将是我的猜测。
从主线程获取控件更新的一种简单方法是使用Grand Central Dispatch(GCD),如下所示:
dispatch_async(dispatch_get_main_queue(), ^{
[outLineView reloadData];
});