Mac NSOutlineView objects being released

perrien

macrumors newbie
Original poster
Apr 26, 2008
20
0
I'm working on a program for 10.8 using ARC so there's no retain/release going on.

What I'll describe is not exactly what I'm doing but will illustrate the problem. I have a Person class with 3 dates, say birthday, graduation and wedding. What I'd like to do is have that Person listed in an outline view With their name as the group and you click the disclosure triangle to get Birthday: 1/2/70, Graduation: 2/3/88, etc.

Initially in
Code:
outlineView:child:ofItem:
I would return, for instance,
Code:
[NSString stringWithFormat: @"Birthday: %@", [person birthday]];
However, after
Code:
outlineView:objectValueForTableColumn:byItem:
displayed that item, the string was being released and the program would crash with EXC_BAD_ACCESS.

Alternately I could return the date in
Code:
outlineView:child:ofItem:
but how would I know what date it was in
Code:
outlineView:objectValueForTableColumn:byItem:
?

The workaround I currently have is to have an NSMutableArray, put the string in there and then return it. The Array basically ups the retain count, it doesn't get released, all works well. But it's kind of an ugly workaround. Does anyone have any suggestions for a more elegant solution?
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
1
Dallas, TX
Trim your code to the smallest amount possible that still exhibits the problem. Once you've done so, post all of your code. We don't know what your properties or intermediate storage looks like. We also don't know exactly what line the code is crashing on. ARC is great, but not a panacea. You may have a subtle error that is not in the tiny snippets you posted. If we can't make it crash it will be much harder to fix.

-Lee
 

perrien

macrumors newbie
Original poster
Apr 26, 2008
20
0
I created a new Cocoa app, put in a outline view and used this code:

Code:
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    return NO;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if (item == nil)
        return 5;
    else
        return 0;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    NSString *results = [NSString stringWithFormat: @"Child %ld", index];
    
    //[_storageArray addObject: results];       /*uncomment this line and it will run correctly*/
    return results;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    return item;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    _storageArray = [NSMutableArray array];
    [outline reloadData];
}
By uncommenting that line, the program will run fine. When commented, it crashes on objectValueForTableColumn.
 

jamawa

macrumors newbie
Jul 7, 2009
10
0
Read the NSOutlineViewDataSource Protocol Reference and especially it's companion guide (Companion guide, data section) carefully (and then possibly again)... :)

Note that
Code:
outlineView:child:ofItem:
is not dealing with whatever it is that needs to be displayed, that is done using
Code:
outlineView:objectValueForTableColumn:byItem:
It needs to return an object that exists outside the routine because it will pass this object to the objectValueForTableColumn method where you can decide what it is you want to have displayed for the column concerned.
In the present form of your routine: the string will only exist outside the routine if you retain it by placing it in an array.

Hope this helps somewhat, let us know.
Jan Martin