NSOutlineView objects being released

Discussion in 'Mac Programming' started by perrien, Aug 26, 2012.

  1. perrien macrumors newbie

    Joined:
    Apr 26, 2008
    #1
    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?
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    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
     
  3. perrien thread starter macrumors newbie

    Joined:
    Apr 26, 2008
    #3
    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.
     
  4. jamawa macrumors newbie

    Joined:
    Jul 7, 2009
    #4
    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
     

Share This Page