In my application I want to search for the files in the mac and if I got the files I need to reload the NSOutlineView with that file. If I reload the items in the NSOutlineView frequently it causes the crash.
// Like this I am calling the method for searching the files.
[self performSelectorInBackground:#selector(searchFiles) withObject:self];
// Reloading the outlineview
- (void)searchFiles {
-------------------------
-------------------------
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:filelistArray forKey:#"children"];
[dictionary setObject:[NSString stringWithFormat:#"%ld",[filelist count]] forKey:#"parent"];
[listArray addObject:dictionary];
[outLineView reloadData];
}
// Delegates for the 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;
}
// Crash Log
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
)
My Question is How do I avoid this crash ?
EDIT 1:
After adding the [outline reloadData]; in dispatch_async(dispatch_get_main_queue(), its working perfectly without any crash. But If I expand some items it leads to crash. I Can't able to figure out the problem. This is my crash log.
*** 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
)
performSelectorInBackground:withObject: runs the selector on a new background thread, while updates (and most other operations) on the UI must be performed on the main thread. Hence the crash, would be my guess.
A simple way to get a control to update from the main thread is to use Grand Central Dispatch (GCD), like this:
dispatch_async(dispatch_get_main_queue(), ^{
[outLineView reloadData];
});
Related
I have a Xamarin.Mac app that crashes when trying to display an alert from the GetView method of a NSOutlineViewDelegate.
The code is the following:
internal class ItemsDelegate : NSOutlineViewDelegate
{
public override NSView GetView(NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item)
{
try
{
//code to return the NSView
}
catch (Exception ex)
{
NSAlert alert = new NSAlert();
alert.InformativeText = message;
alert.RunModal();
}
}
}
So, what it happens is that a controlled exception is thrown in the code to return the NSView.
When trying to show it with the NSAlert, in the catch block and the "alert.RunModal()" is executed, the app crashes.
The crash exception is the following:
Terminating app due to uncaught exception 'NSGenericException', reason: '-[NSAlert runModal] may not be invoked inside of transaction commit (usually this means it was invoked inside of a view's -drawRect: method.)'
First throw call stack:
(
0 CoreFoundation 0x00007fffca9976fb _exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fffdf33ba2a objc_exception_throw + 48
2 CoreFoundation 0x00007fffcaa149a5 +[NSException raise:format:] + 197
3 AppKit 0x00007fffc8d2eeaa _NSRunModal + 266
4 AppKit 0x00007fffc876c591 -[NSAlert runModal] + 270
5 macplastic 0x0000000107c97b39 xamarin_dyn_objc_msgSend + 217
6 ??? 0x0000000116c14f2b 0x0 + 4676734763
7 ??? 0x0000000116b06825 0x0 + 4675627045
8 ??? 0x0000000116a62808 0x0 + 4674955272
9 ??? 0x0000000116a62b8e 0x0 + 4674956174
10 macplastic 0x0000000107d9a340 mono_jit_runtime_invoke + 2272
11 macplastic 0x0000000107e4b3c8 do_runtime_invoke + 88
12 macplastic 0x0000000107e4b2d6 mono_runtime_invoke + 102
13 macplastic 0x0000000107c9583d xamarin_invoke_trampoline + 5725
14 macplastic 0x0000000107c965bd xamarin_arch_trampoline + 189
15 macplastic 0x0000000107c979b1 xamarin_x86_64_common_trampoline + 110
16 AppKit 0x00007fffc85b4f84 -[NSTableView(NSTableViewViewBased) makeViewForTableColumn:row:] + 76
17 AppKit 0x00007fffc85b495b -[NSTableRowData _addViewToRowView:atColumn:row:] + 308
18 AppKit 0x00007fffc85b469f -[NSTableRowData _addViewsToRowView:atRow:] + 204
19 AppKit 0x00007fffc85b2e47 -[NSTableRowData _initializeRowView:atRow:] + 390
20 AppKit 0x00007fffc85b144d -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 398
21 AppKit 0x00007fffc85b1208 -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 316
22 AppKit 0x00007fffc85b0030 -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 1647
23 AppKit 0x00007fffc85af923 -[NSTableRowData updateVisibleRowViews] + 232
24 AppKit 0x00007fffc85af27a -[NSTableView layout] + 178
25 AppKit 0x00007fffc8d19afc _NSViewLayout + 450
26 AppKit 0x00007fffc8550074 -[NSView _doLayout] + 126
27 AppKit 0x00007fffc854fbf9 -[NSView _layoutSubtreeWithOldSize:] + 497
28 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
29 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
30 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
31 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
32 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
33 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
34 AppKit 0x00007fffc854fec7 -[NSView _layoutSubtreeWithOldSize:] + 1215
35 AppKit 0x00007fffc8d1fe89 -[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 1517
36 AppKit 0x00007fffc856e3f1 -[NSWindow(NSConstraintBasedLayout) _layoutViewTree] + 163
37 AppKit 0x00007fffc85dd52a -[NSWindow(NSConstraintBasedLayout) layoutIfNeeded] + 269
38 AppKit 0x00007fffc8d49f78 _NSWindowGetDisplayCycleObserver_block_invoke.6213 + 67
39 AppKit 0x00007fffc85eec89 _37+[NSDisplayCycle currentDisplayCycle]_block_invoke + 454
40 QuartzCore 0x00007fffd045a1ba _ZN2CA11Transaction19run_commit_handlersE18CATransactionPhase + 46
41 QuartzCore 0x00007fffd0561e10 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 160
42 QuartzCore 0x00007fffd0458d55 _ZN2CA11Transaction6commitEv + 475
43 AppKit 0x00007fffc88d0d99 _37+[NSDisplayCycle currentDisplayCycle]_block_invoke.31 + 323
44 CoreFoundation 0x00007fffca92dec7 _CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
45 CoreFoundation 0x00007fffca92de37 _CFRunLoopDoObservers + 391
46 CoreFoundation 0x00007fffca90ed79 _CFRunLoopRun + 873
47 CoreFoundation 0x00007fffca90e7b4 CFRunLoopRunSpecific + 420
48 HIToolbox 0x00007fffc9e9e2ac RunCurrentEventLoopInMode + 240
49 HIToolbox 0x00007fffc9e9e0e1 ReceiveNextEventCommon + 432
50 HIToolbox 0x00007fffc9e9df16 _BlockUntilNextEventMatchingListInModeWithFilter + 71
51 AppKit 0x00007fffc84a06cd _DPSNextEvent + 1093
52 AppKit 0x00007fffc8c17830 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 2730
53 AppKit 0x00007fffc849506d -[NSApplication run] + 926
54 AppKit 0x00007fffc845f983 NSApplicationMain + 1237
55 ??? 0x000000010c7cc9d2 0x0 + 4504472018
56 ??? 0x000000010c7cc5cd 0x0 + 4504470989
57 macplastic 0x0000000107d9a340 mono_jit_runtime_invoke + 2272
58 macplastic 0x0000000107e4b3c8 do_runtime_invoke + 88
59 macplastic 0x0000000107e4d8a0 mono_runtime_exec_main + 896
60 macplastic 0x0000000107e4d45d mono_runtime_run_main + 909
61 macplastic 0x0000000107cefca7 mono_jit_exec + 247
62 macplastic 0x0000000107cf2022 mono_main + 8098
63 macplastic 0x0000000107c982c4 xamarin_main + 980
64 macplastic 0x0000000107c98fd4 main + 36
65 macplastic 0x0000000107c7f944 start + 52
66 ??? 0x0000000000000002 0x0 + 2
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Any help?
Also, why does the app crash even if you add a try/catch block?? Is there any way to avoid the crash??
try
{
NSAlert alert = new NSAlert();
alert.InformativeText = message;
alert.RunModal();
}
catch (Exception ex)
{
//Nothing to do, we did our best to show the error message, avoid an unhandled crash.
}
Any help would be much appreciated.
I have a NSTableView that is populated by an array called tableArray. I have a button that is supposed to remove the selected item from the array. In my removeItem: method:
[tableArray removeObjectAtIndex:[tableView selectedRow];
[tableView reloadData];
But I get the error:
2015-05-13 18:16:45.283 FileShedb1.0[979:303] *** -[__NSArrayM objectAtIndex:]: index 18446744073709551615 beyond bounds [0 .. 0]
2015-05-13 18:16:45.288 FileShedb1.0[979:303] (
0 CoreFoundation 0x00007fff8d35ff56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff93119d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8d2ed392 -[__NSArrayM objectAtIndex:] + 274
3 FileShedb1.0 0x00000001000028a9 -[MPOMainWindowController tableViewSelectionDidChange:] + 201
4 Foundation 0x00007fff8cca0d0e __-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_1 + 47
5 CoreFoundation 0x00007fff8d3087ba _CFXNotificationPost + 2634
6 Foundation 0x00007fff8cc8cfc3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 65
7 AppKit 0x00007fff8ab10049 -[NSTableView _sendSelectionChangedNotificationForRows:columns:] + 203
8 AppKit 0x00007fff8aae6b0a -[NSTableView _enableSelectionPostingAndPost] + 425
9 AppKit 0x00007fff8aadcd75 -[NSTableView _tileAndRedisplayAll] + 358
10 FileShedb1.0 0x00000001000027bc -[MPOMainWindowController removeFile:] + 188
11 CoreFoundation 0x00007fff8d34f70d -[NSObject performSelector:withObject:] + 61
12 AppKit 0x00007fff8aaa98ca -[NSApplication sendAction:to:from:] + 139
13 AppKit 0x00007fff8aaa97fe -[NSControl sendAction:to:] + 88
14 AppKit 0x00007fff8aaa9729 -[NSCell _sendActionFrom:] + 137
15 AppKit 0x00007fff8aaa8bec -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
16 AppKit 0x00007fff8ab28b74 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
17 AppKit 0x00007fff8aaa77f6 -[NSControl mouseDown:] + 786
18 AppKit 0x00007fff8aa72c98 -[NSWindow sendEvent:] + 6306
19 AppKit 0x00007fff8aa0c3a5 -[NSApplication sendEvent:] + 5593
20 AppKit 0x00007fff8a9a2a0e -[NSApplication run] + 555
21 AppKit 0x00007fff8ac1eeac NSApplicationMain + 867
22 FileShedb1.0 0x00000001000014c2 main + 34
23 FileShedb1.0 0x0000000100001494 start + 52
)
Anyone know why i'm getting the error?
If no row is selected, selectedRow row returns -1. Put a check for this.
Checkout apple's documentation.
So I am building an app in cocoa and having a bit of trouble. I want to feed text file names in many different folders to a tableview using an array controller, but it keeps throwing out of bounds errors. Heres a chunk of the code giving me trouble.
[self clear:nil]; // method that clears the NSTableView
NSString *chooserSelection = chooserItems.titleOfSelectedItem; // gets the selected folder from an NSPopUpButton
if (chooserSelection == #"All") {
path = #"/Library/Application Support/File Folder/Files/";
NSArray *folders = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSLog(#"\nfolders = %#", folders);
for (int i = 0; i < [folders count]; i++) {
path = #"/Library/Application Support/File Folder/Files/";
NSMutableString *folderNames = [[NSMutableString stringWithString:path] init];
[folderNames insertString:folders[i] atIndex:folderNames.length];
[folderNames insertString:#"/" atIndex:folderNames.length];
NSArray *text = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderNames error:nil];
[myArrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:text[i], #"File Name", nil]];
//This line gives the error
}
}
If I change [folders count] to 1 it shows up in the NSTableView. However on anything past that (additional passes through the for loop) i get an out of bounds error.
2013-02-26 13:17:49.679 AppName[3489:403] *** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]
2013-02-26 13:17:49.683 AppName[3489:403] (
0 CoreFoundation 0x00007fff829b5f56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff84fe6d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8295f370 -[__NSArrayI objectAtIndex:] + 208
3 AppName 0x000000010000159a -[AppDelegate tableView:objectValueForTableColumn:row:] + 106
4 AppKit 0x00007fff840a16e7 -[NSTableView _dataSourceValueForColumn:row:] + 73
5 AppKit 0x00007fff840a1167 -[NSTableView preparedCellAtColumn:row:] + 437
6 AppKit 0x00007fff840b2171 -[NSTableView _drawContentsAtRow:column:withCellFrame:] + 42
7 AppKit 0x00007fff840b05d8 -[NSTableView drawRow:clipRect:] + 1647
8 AppKit 0x00007fff840afdb5 -[NSTableView drawRowIndexes:clipRect:] + 565
9 AppKit 0x00007fff840aded7 -[NSTableView drawRect:] + 1390
10 AppKit 0x00007fff84197382 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inContext:topView:] + 1435
11 AppKit 0x00007fff841b564f __-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke_1 + 94
12 AppKit 0x00007fff841b52fb -[NSView(NSLayerKitGlue) _drawViewBackingLayer:inContext:drawingHandler:] + 2001
13 QuartzCore 0x00007fff82c4a0dc -[CALayer drawInContext:] + 145
14 QuartzCore 0x00007fff82c49225 CABackingStoreUpdate_ + 3221
15 QuartzCore 0x00007fff82c4813a _ZN2CA5Layer8display_Ev + 1086
16 AppKit 0x00007fff841504e6 -[NSView(NSInternal) _recursiveDisplayViewsIntoLayersIfNeeded] + 163
17 AppKit 0x00007fff841505fc -[NSView(NSInternal) _recursiveDisplayViewsIntoLayersIfNeeded] + 441
18 AppKit 0x00007fff841505fc -[NSView(NSInternal) _recursiveDisplayViewsIntoLayersIfNeeded] + 441
19 AppKit 0x00007fff841505fc -[NSView(NSInternal) _recursiveDisplayViewsIntoLayersIfNeeded] + 441
20 AppKit 0x00007fff84150168 -[NSView(NSLayerKitGlue) _drawRectAsLayerTree:] + 128
21 AppKit 0x00007fff8401653e -[NSView _drawRect:clip:] + 4382
22 AppKit 0x00007fff8401406d -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3020
23 AppKit 0x00007fff84014b5e -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5821
24 AppKit 0x00007fff84012da3 -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 270
25 AppKit 0x00007fff8400e1bb -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4755
26 AppKit 0x00007fff84006c35 -[NSView displayIfNeeded] + 1676
27 AppKit 0x00007fff84006375 _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 648
28 CoreFoundation 0x00007fff829758e7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
29 CoreFoundation 0x00007fff82975846 __CFRunLoopDoObservers + 374
30 CoreFoundation 0x00007fff8294aaf9 __CFRunLoopRun + 825
31 CoreFoundation 0x00007fff8294a486 CFRunLoopRunSpecific + 230
32 AppKit 0x00007fff84459b08 -[NSMenu _internalPerformActionForItemAtIndex:] + 38
33 AppKit 0x00007fff842e86f9 -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] + 138
34 AppKit 0x00007fff841349bb NSSLMMenuEventHandler + 339
35 HIToolbox 0x00007fff89d08234 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1263
36 HIToolbox 0x00007fff89d07840 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 446
37 HIToolbox 0x00007fff89d1e6db SendEventToEventTarget + 76
38 HIToolbox 0x00007fff89d647b5 _ZL18SendHICommandEventjPK9HICommandjjhPKvP20OpaqueEventTargetRefS5_PP14OpaqueEventRef + 398
39 HIToolbox 0x00007fff89e4be2d SendMenuCommandWithContextAndModifiers + 56
40 HIToolbox 0x00007fff89e935b5 SendMenuItemSelectedEvent + 253
41 HIToolbox 0x00007fff89d5d883 _ZL19FinishMenuSelectionP13SelectionDataP10MenuResultS2_ + 101
42 HIToolbox 0x00007fff89e8bfed _ZL19PopUpMenuSelectCoreP8MenuData5PointdS1_tjPK4RecttjS4_S4_PK10__CFStringPP13OpaqueMenuRefPt + 1660
43 HIToolbox 0x00007fff89e8c2ac _HandlePopUpMenuSelection7 + 621
44 AppKit 0x00007fff842eb3c5 _NSSLMPopUpCarbonMenu3 + 3860
45 AppKit 0x00007fff846990fa _NSPopUpCarbonMenu3 + 39
46 AppKit 0x00007fff842e952a -[NSCarbonMenuImpl popUpMenu:atLocation:width:forView:withSelectedItem:withFont:withFlags:withOptions:] + 322
47 AppKit 0x00007fff844ca1f1 -[NSPopUpButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 564
48 AppKit 0x00007fff840cb7f6 -[NSControl mouseDown:] + 786
49 AppKit 0x00007fff84096c98 -[NSWindow sendEvent:] + 6306
50 AppKit 0x00007fff840303a5 -[NSApplication sendEvent:] + 5593
51 AppKit 0x00007fff83fc6a0e -[NSApplication run] + 555
52 AppKit 0x00007fff84242eac NSApplicationMain + 867
53 AppName 0x0000000100001152 main + 34
54 AppName 0x0000000100001124 start + 52
)
I can also more the addObject line to the line below the for loop which will display the filename of the last file. But I cannot figure out where the out of bounds error is coming from.
You are using the index i first for the count of folders in path, and then for the count of files in that respective folder. So you are depending on there being at least as many files in folder N as the number of N.
For example if you have three folders
folder0
folder1
folder2
then when you iterate over folder2 (i=2), there had better be at least 3 items in the folder as you are accessing item 3 (text[2]). When there are fewer items, you will get that out-of-bounds error.
You probably mean to do something like this:
NSMutableDictionary* dict =
[NSMutableDictionary dictionaryWithObjectsAndKeys:text, folders[i], nil];
That will get you an array of dictionaries. Each dictionary has a single key (the name of the folder,) and a single value (an array of filenames).
You could simplify your data structure further by flattening this to a single dictionary (not inside an array). Each key is a folder name, each value is the array of filenames.
In order to work with the IKImageBrowserView, one must implement a datasource with the following methods
– numberOfItemsInImageBrowser:
– imageBrowser:itemAtIndex:
This is not dissimilar to NSTableView, which has the following datasource methods
– numberOfRowsInTableView:
– tableView:objectValueForTableColumn:row:
However, the disturbing difference is that whereas NSTableView takes into account what's currently visible before calling – tableView:objectValueForTableColumn:row:, IKImageBrowserView seems to iterate over the entire range given in – numberOfItemsInImageBrowser: and ask for imageBrowser:itemAtIndex:. Unfortunately, the datasource is sometimes backed by hundreds of thousands of items, loading all the unnecessary ones is a terrible waste. Is there anyway to make IKImageBrowserView only load the items visible, (+preloading of course) just like the NSTableView does?
Update
I tried writing a NSProxy subclass and it indeed worked. (well, more on that in a sec) It looks like this
// .h file
#import <Foundation/Foundation.h>
#interface ILArrayItemProxy : NSProxy
- (id)initWithArray:(id)array index:(NSUInteger)index;
+ (id)proxyWithArray:(id)array index:(NSUInteger)index;
#end
// .m file
#import "ILArrayItemProxy.h"
#interface ILArrayItemProxy() {
id _array;
NSUInteger _index;
}
#property (readonly) id target;
#end
#implementation ILArrayItemProxy
- (id)initWithArray:(id)array index:(NSUInteger)index {
_array = array;
_index = index;
return self;
}
- (id)target {
return [_array objectAtIndex:_index];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
+ (id)proxyWithArray:(id)array index:(NSUInteger)index {
return [[ILArrayItemProxy alloc] initWithArray:array index:index];
}
#end
Now, when the imageBrowser asks for – imageBrowser:itemAtIndex:, I would return
[ILArrayItemProxy proxyWithArray:self.arrangedObjects index:index];
This works very well! Lazy loading is indeed achieved and I am no longer retrieving all the objects from the store at once. However, upon calling reloadData on any of the views, troubles ensue.
Here is the error message from NSTableView
Cannot update for observer <NSAutounbinderObservance 0x105889dd0> for the key path
"objectValue.status" from <NSTableCellView 0x105886a80>, most likely because the value
for the key "objectValue" has changed without an appropriate KVO notification being sent.
Check the KVO-compliance of the NSTableCellView class.
2012-01-29 11:48:01.304 [62895:707] (
0 CoreFoundation 0x00007fff92bf6286 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff91d3ad5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff92bf60ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff92bf6044 +[NSException raise:format:] + 116
4 Foundation 0x00007fff9154b519 -[NSKeyValueNestedProperty object:withObservance:didChangeValueForKeyOrKeys:recurse:forwardingValues:] + 689
5 Foundation 0x00007fff9154986f NSKeyValueDidChange + 186
6 Foundation 0x00007fff914f60fb -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 130
7 AppKit 0x00007fff90a2c26d -[NSTableRowData _addViewToRowView:atColumn:row:] + 434
8 AppKit 0x00007fff90a2bf81 -[NSTableRowData _addViewsToRowView:atRow:] + 200
9 AppKit 0x00007fff90a2abe3 -[NSTableRowData _addRowViewForVisibleRow:withPriorView:] + 404
10 AppKit 0x00007fff90a2a9e2 -[NSTableRowData _addRowViewForVisibleRow:withPriorRowIndex:inDictionary:withRowAnimation:] + 184
11 AppKit 0x00007fff90a2a928 -[NSTableRowData _addRowViewForVisibleRow:] + 38
12 AppKit 0x00007fff90a2a06c -[NSTableRowData _unsafeUpdateVisibleRowEntries] + 448
13 AppKit 0x00007fff90a29e87 -[NSTableRowData updateVisibleRowViews] + 95
14 AppKit 0x00007fff909c1c56 -[NSTableView viewWillDraw] + 156
15 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
16 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
17 AppKit 0x00007fff909254a2 -[NSScrollView viewWillDraw] + 43
18 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
19 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
20 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
21 AppKit 0x00007fff90924f7b -[NSSplitView viewWillDraw] + 67
22 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
23 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
24 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
25 AppKit 0x00007fff90924f7b -[NSSplitView viewWillDraw] + 67
26 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
27 AppKit 0x00007fff90924c11 -[NSView viewWillDraw] + 666
28 AppKit 0x00007fff90923952 -[NSView _sendViewWillDrawInRect:clipRootView:suppressRecursion:] + 1358
29 AppKit 0x00007fff909226c1 -[NSView displayIfNeeded] + 1039
30 AppKit 0x00007fff9091e6fa -[NSAnimationManager animationTimerFired:] + 2593
31 Foundation 0x00007fff91537014 __NSFireTimer + 102
32 CoreFoundation 0x00007fff92baaf84 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
33 CoreFoundation 0x00007fff92baaad6 __CFRunLoopDoTimer + 534
34 CoreFoundation 0x00007fff92b8b471 __CFRunLoopRun + 1617
35 CoreFoundation 0x00007fff92b8aae6 CFRunLoopRunSpecific + 230
36 HIToolbox 0x00007fff8cdf63d3 RunCurrentEventLoopInMode + 277
37 HIToolbox 0x00007fff8cdfd58f ReceiveNextEventCommon + 181
38 HIToolbox 0x00007fff8cdfd4ca BlockUntilNextEventMatchingListInMode + 62
39 AppKit 0x00007fff908e63f1 _DPSNextEvent + 659
40 AppKit 0x00007fff908e5cf5 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
41 AppKit 0x00007fff908e262d -[NSApplication run] + 470
42 AppKit 0x00007fff90b6180c NSApplicationMain + 867
IKImageBrowserView on the other hand would just hang on me without any kind of error message if I were to call its reloadData.
So yea, I managed to replace one problem with another, c'est la vie?
I try to do a simple program in cocoa, a NSTabVew with 2 items, in the first item I set a content to a string var, in the second tab I display this value. I create two Object class (Prima and Seconda), than I add 2 object in IB setting like Prima and Seconda
Prima.m
- (IBAction) salva:(id) sender{
nome = [field stringValue];
NSLog(#"%#",nome);
}
Seconda.m
- (IBAction) visualizza:(id) sender{
NSString *dato;
Prima *prima = [[Prima alloc] init];
dato = prima.nome;
[label setStringValue:dato];
}
when I run the program I get this error:
2011-10-03 11:42:43.511 Prova[44622:707] *** Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit-1138/AppKit.subproj/NSCell.m:1564
2011-10-03 11:42:43.511 Prova[44622:707] Invalid parameter not satisfying: aString != nil
2011-10-03 11:42:43.513 Prova[44622:707] (
0 CoreFoundation 0x00007fff8d497986 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff90ed9d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8d4977ba +[NSException raise:format:arguments:] + 106
3 Foundation 0x00007fff8cce914f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 169
4 AppKit 0x00007fff88957685 -[NSCell _objectValue:forString:errorDescription:] + 160
5 AppKit 0x00007fff889575df -[NSCell _objectValue:forString:] + 19
6 AppKit 0x00007fff88957545 -[NSCell setStringValue:] + 41
7 AppKit 0x00007fff88a58039 -[NSControl setStringValue:] + 115
8 Prova 0x0000000100001365 -[Seconda visualizza:] + 133
9 CoreFoundation 0x00007fff8d48711d -[NSObject performSelector:withObject:] + 61
10 AppKit 0x00007fff88a3f852 -[NSApplication sendAction:to:from:] + 139
11 AppKit 0x00007fff88a3f784 -[NSControl sendAction:to:] + 88
12 AppKit 0x00007fff88a3f6af -[NSCell _sendActionFrom:] + 137
13 AppKit 0x00007fff88a3eb7a -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2014
14 AppKit 0x00007fff88abe57c -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 489
15 AppKit 0x00007fff88a3d786 -[NSControl mouseDown:] + 786
16 AppKit 0x00007fff88a0866e -[NSWindow sendEvent:] + 6280
17 AppKit 0x00007fff889a0f19 -[NSApplication sendEvent:] + 5665
18 AppKit 0x00007fff8893742b -[NSApplication run] + 548
19 AppKit 0x00007fff88bb552a NSApplicationMain + 867
20 Prova 0x0000000100000f92 main + 34
21 Prova 0x0000000100000f64 start + 52
22 ??? 0x0000000000000001 0x0 + 1
)
where is the error for you?
It seems that dato is nil, which (based on what you've given us) is probably because things aren't hooked up right in the XIB. Without more information I can't say more.