我有一個標準的NSTableView基於單元格的內容模式,它的dataSource是一個數組控制器附加到我的AppDelegate的managedObjectContext。在代表,該代碼刪除在後臺線程對象(DB可以有30K +對象,所以這是很好的有一個響應的用戶界面和一個進度條和取消選項):NSTableView錯誤:行1應該在有效的可見部分
-(void)deleteObjects:(NSArray*)objs completionBlock:(void (^)(void))aBlock
{
[self showCancelButton:YES];
__block __typeof__(self) blockself = self;
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_async(dispatchGroup, dispatch_get_global_queue(0, 0), ^{
NSManagedObjectContext *mainContext = [(AppDelegate*)[[NSApplication sharedApplication] delegate] managedObjectContext];
[objs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[mainContext deleteObject:obj];
if ((idx % saveSpace == 0) && (idx > 0)) {
dispatch_sync(dispatch_get_main_queue(), ^{
NSError *error;
[blockself.managedObjectContext save:&error];
theProgressOverlay.filesCount -= saveSpace; //
});
}
if (isCancelled) {
*stop = TRUE;
}
}];
NSError *error;
[mainContext save:&error];
NSLog(@"delete error: %@",error);
if (aBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
[self showCancelButton:NO];
aBlock();
});
}
});
}
這個方法是由被叫代碼:
NSFetchRequest *toDelFetch = [NSFetchRequest fetchRequestWithEntityName:entity];
[toDelFetch setIncludesPropertyValues:NO];
NSError *error;
NSArray *toDelObjs = [self.managedObjectContext executeFetchRequest:toDelFetch error:&error];
NSLog(@"Error: %@",error);
if (!toDelObjs || toDelObjs.count < 1) {
return FALSE;
}
[self deleteObjects:toDelObjs completionBlock:{NSLog(@"Finished");}];
這一切似乎很好地工作:用戶界面的響應和取消按鈕總是工作,但每隔一段時間我得到的錯誤:
2012-12-13 19:31:53.352 QS[1399:403] *** Assertion failure in -[NSTableRowData _addRowViewForVisibleRow:withPriorView:], /SourceCache/AppKit/AppKit-1138.51/TableView.subproj/NSTableRowData.m:2484
2012-12-13 19:31:53.353 QS[1399:403] Row 1 should be in the valid visible section
2012-12-13 19:31:53.358 QS[1399:403] (
0 CoreFoundation 0x00007fff8b773f56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff88715d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8b773d8a +[NSException raise:format:arguments:] + 106
3 Foundation 0x00007fff8db1a71f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 169
4 AppKit 0x00007fff917c6003 -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 164
5 AppKit 0x00007fff917c5ef2 -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 184
6 AppKit 0x00007fff917c5e38 -[NSTableRowData _addRowViewForVisibleRow:] + 38
7 AppKit 0x00007fff917c557c -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 448
8 AppKit 0x00007fff917c5397 -[NSTableRowData updateVisibleRowViews] + 95
9 AppKit 0x00007fff9175d854 -[NSTableView viewWillDraw] + 156
10 AppKit 0x00007fff916c1f08 -[NSView viewWillDraw] + 666
11 AppKit 0x00007fff916c1f08 -[NSView viewWillDraw] + 666
12 AppKit 0x00007fff916c2796 -[NSScrollView viewWillDraw] + 43
13 AppKit 0x00007fff916c1f08 -[NSView viewWillDraw] + 666
14 AppKit 0x00007fff916c1f08 -[NSView viewWillDraw] + 666
15 AppKit 0x00007fff916c0c4d -[NSView _sendViewWillDrawInRect:clipRootView:suppressRecursion:] + 1358
16 AppKit 0x00007fff916bf9b8 -[NSView displayIfNeeded] + 1039
17 AppKit 0x00007fff916bf375 _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 648
18 CoreFoundation 0x00007fff8b7338e7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
19 CoreFoundation 0x00007fff8b733846 __CFRunLoopDoObservers + 374
20 CoreFoundation 0x00007fff8b708af9 __CFRunLoopRun + 825
21 CoreFoundation 0x00007fff8b708486 CFRunLoopRunSpecific + 230
22 HIToolbox 0x00007fff8cb352bf RunCurrentEventLoopInMode + 277
23 HIToolbox 0x00007fff8cb3c4bf ReceiveNextEventCommon + 181
24 HIToolbox 0x00007fff8cb3c3fa BlockUntilNextEventMatchingListInMode + 62
25 AppKit 0x00007fff91683779 _DPSNextEvent + 659
26 AppKit 0x00007fff9168307d -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
27 AppKit 0x00007fff9167f9b9 -[NSApplication run] + 470
28 AppKit 0x00007fff918fbeac NSApplicationMain + 867
29 QuickSlide 0x00000001000019c2 main + 34
30 QuickSlide 0x0000000100001994 start + 52
與我們d搜查耳邊的朋友谷歌顯示了一些博客,指出Row 1 should be in the valid visible section
是NSTableView的-reloadData
稱爲'太早',即-awakeFromNib
期間的錯誤。但對我而言,情況並非如此 - 應用程序完全清醒後肯定會發生刪除操作。我也註釋掉showCancelButton:
,以確保它不是我的自定義進度欄,並試圖
[contentArrayController setAutomaticallyRearrangesObjects:NO];
誰能告訴我,如果有一個狡猾的手段來避免這種斷言?或者即使這很重要?該應用程序似乎仍然可以繼續,但我看到的其中一個博客說,它爲後來儲存了麻煩,但沒有詳細說明。在錯誤發生後,表似乎會更慢地刷新自己。