UIViewController push new view crashes app

Discussion in 'iOS Programming' started by linuxaos, May 19, 2010.

  1. linuxaos macrumors newbie

    Joined:
    May 17, 2010
    #1
    This is the issue:

    From my main "UITableViewController" I want to show two different views. One is another "UITableViewController" and the other view is a "UIViewController".

    From the main "UITableViewController" when I call the "UIViewController" I do:
    Code:
    	UIViewController *sortController = [[SortMain alloc] init];
    	[[self navigationController] pushViewController:sortController
                   animated:YES];
    	[myViewController release];
    
    Now When I do this, when the "UIViewController" returns to "UITableViewController" the app crashes with:
    Code:
    Program received signal:  “EXC_BAD_ACCESS”.
    (gdb) bt
    #0  0x916b9edb in objc_msgSend ()
    #1  0x03908f40 in ?? ()
    #2  0x035d4187 in CALayerUpdateSublayers ()
    #3  0x035d26d1 in -[CALayer dealloc] ()
    #4  0x035c4526 in CALayerRelease ()
    #5  0x035cd305 in CALayerFreeTransaction ()
    #6  0x035c55d0 in CA::Transaction::commit ()
    #7  0x035cd838 in CA::Transaction::observer_callback ()
    #8  0x01e34252 in __CFRunLoopDoObservers ()
    #9  0x01e3365f in CFRunLoopRunSpecific ()
    #10 0x01e32c48 in CFRunLoopRunInMode ()
    #11 0x025c978d in GSEventRunModal ()
    #12 0x025c9852 in GSEventRun ()
    #13 0x00331003 in UIApplicationMain ()
    #14 0x00002923 in main (argc=1, argv=0xbffff014) at /opt/mycode/iPhone/myapp/Classes/main.m:28
    
    When the main "UITableViewController" calls the secondary "UITableViewController" like this:

    Code:
    	UIViewController *detailsController = [[DetailsMain alloc] init];
    	[[self navigationController] pushViewController:detailsController
                          animated:YES];
    	[myViewController release];	
    
    This does not crash!

    So, why is it ok to release when I call a "UITableViewController" and not ok when I call a "UIViewController".

    And this behavior is the same if the main controller is also a "UIViewController".

    Thanks in advance.
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    What does your init method look like for SortMain and DetailsMain?
     
  3. linuxaos thread starter macrumors newbie

    Joined:
    May 17, 2010
    #3
    Resolved!

    After a very long debugging session, this is what the problem turned out to be:

    The "UIViewController" (the one that crashed the app) had a line:
    Code:
    labelLine = [[[UILabel alloc]
        initWithFrame:CGRectMake(0, 10, cgSize.width, LINELABELHEIGHT) ]
        autorelease];
    
    However, the problem was that in method: "dealloc" I was also doing a:
    Code:
    [labelLine release];
    
    Note that this did not crash the app!

    What messed me up was that it was the "release" (on the top level controller) of the "UIViewController", was crashing the app!
    I don't know by what logic this was happening. I'll figure it out tomorrow.
    Now, I'm fried.

    So, I was on the wrong path all along.

    I found the error by pure luck. I commented out all the statements on the "UIViewController" dealloc method
    and I noticed that I was not crashing anymore. Then by pure accident I put back only the:
    Code:
    [[super dealloc];
    
    line and I was still ok. Then I double checked the "labelLine" alloc and there it was: "autorelease".

    I am really sorry if I confused anyone. Feel free to send me hate mail :(
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    It's crucial that you show how variables are declared, in order to understand what is happening. Different things have different lifetimes, and lifetime is the essence of memory management.

    If labelLine is an ivar, then you're doing this wrong. If labelLine is an automatic variable that is assigned to an ivar, without a retain, then that is equally wrong. But if you perform an extra retain to counteract the autorelease, you could get the same effect by not autoreleasing and not using an overt retain. It looks like you don't fully understand what autorelease is for, nor what it does.

    The autorelease message effectively GIVES UP OWNERSHIP of an owned object. It does not immediately release the object. Instead, it transfers ownership to the autorelease pool. The owner, i.e. the pool, will then perform an actual release on the object at some later time, when it's drained. If no other object has taken ownership by that later time, specifically by calling retain, then the autoreleased object will be destroyed.

    If you need something to stay alive, you must take ownership and retain it. You must not reverse that retain, either by release or autorelease, until you no longer need the object to stay alive.

    Memory management problems don't always crash the app. Or they may crash the app at a later time and far distant place than when and where the real problem lies.

    One technique for finding overreleases is to enable zombies. Google NSZombieEnabled.
     
  5. linuxaos thread starter macrumors newbie

    Joined:
    May 17, 2010
    #5
    Sorry, I did not include the declaration of labeLline.

    In the "controller.h" file it is declared as:

    Code:
    IBOutlet UILabel *labelLine;
    
    and then:
    
    @property (nonatomic, retain) UILabel *labelLine;
    
    Then, of course, there is also a "@synthesize" statement in the ".m" file.

    I was tired after a long session. Apologies!
     

Share This Page