Out of bounds error on addObject to NSMutableDictionary - cocoa

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.

Related

removeobjectAtIndex: causes index to be -1;

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.

Reloading NSOutlineView frequently causes crashes

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

IKImageBrowserView lazy loading?

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?

textView:shouldChangeTextInRanges:replacementStrings: method crashes when NSTextStorage is edited

I'm new to Cocoa programming under OSX Lion, so this is a question I cannot find answer to.
I need to modify an attributed string which is entered by the user through the NSTextView.
Editing may include replacement of some portion(s) of the string inside the NSTextStorage and addition of NSTextAttachment objects.
I implemented the protocol and provided it for NSTextView instance as delegate.
I also implemented the method textView:shouldChangeTextInRanges:replacementStrings: in the next manner:
- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRanges:(NSArray *)affectedRanges replacementStrings:(NSArray *)replacementStrings{
NSTextStorage* ts=[textView textStorage];
[ts beginEditing];
NSMutableString* buf=[ts mutableString];
//make some completions
NSRange rng;
rng.location=0;
rng.length=[buf length];
[buf replaceOccurrencesOfString:#"(." withString:#"(0." options:0 range:rng];
rng.location=0;
rng.length=[buf length];
[buf replaceOccurrencesOfString:#"-+" withString:#"-" options:0 range:rng];
rng.location=0;
rng.length=[buf length];
[buf replaceOccurrencesOfString:#"+-" withString:#"-" options:0 range:rng];
[ts endEditing];
return YES;
}
Thus I try the next scenario: when the application is up, the user types inside the NSTextView some text. If he types "(." everything is going well. But when he types "-+ " (minus, plus, whitespace) - the method crashes producing this dump:
[NSConcreteTextStorage attributesAtIndex:effectiveRange:]: Range or index out of bounds
(
0 CoreFoundation 0x00007fff95963286 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8c32bd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff959630ba +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff95963044 +[NSException raise:format:] + 116
4 AppKit 0x00007fff90acb5bd -[NSConcreteTextStorage attributesAtIndex:effectiveRange:] + 121
5 AppKit 0x00007fff90f4cde6 -[NSTextView insertText:replacementRange:] + 840
6 AppKit 0x00007fff910fc891 -[NSTextInputContext handleTSMEvent:] + 2289
7 AppKit 0x00007fff910fe4fe _NSTSMEventHandler + 165
8 HIToolbox 0x00007fff89745308 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1263
9 HIToolbox 0x00007fff89744914 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 446
10 HIToolbox 0x00007fff8975b6c7 SendEventToEventTarget + 76
11 HIToolbox 0x00007fff89930a4d SendTSMEvent + 35
12 HIToolbox 0x00007fff89930dd4 SendUnicodeTextAEToUnicodeDoc + 452
13 HIToolbox 0x00007fff8993095e TSMKeyEvent + 629
14 HIToolbox 0x00007fff8976f81a TSMProcessRawKeyEvent + 2350
15 AppKit 0x00007fff910fbade -[NSTextInputContext handleEvent:] + 639
16 AppKit 0x00007fff90fc7eaf -[NSView interpretKeyEvents:] + 248
17 AppKit 0x00007fff90f40c65 -[NSTextView keyDown:] + 691
18 AppKit 0x00007fff90a20544 -[NSWindow sendEvent:] + 7430
19 AppKit 0x00007fff909b868f -[NSApplication sendEvent:] + 5593
20 AppKit 0x00007fff9094e682 -[NSApplication run] + 555
21 AppKit 0x00007fff90bcd80c NSApplicationMain + 867
22 myapp 0x0000000100001302 main + 34
23 myapp 0x00000001000012d4 start + 52
It seems that shortened string causes some out-of-bounds spill.
What am I doing wrong and how can I fix this issue? Please help.
The -length method returns the quantity of characters in a NSString. The problem is that the first character is in the index 0. Try using [buf length] - 1. This should work.

Passing value between NSTabView

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.

Resources