Application crashes when releasing an object

Discussion in 'iOS Programming' started by Nicsoft, Dec 28, 2009.

  1. Nicsoft macrumors member

    Joined:
    Oct 17, 2009
    Location:
    Stockholm
    #1
    Hello,

    I am instantiating a UIViewController (gameBoardViewController below) that is File's Owner to a custom view (associated to a view created in IB).

    First time I load it there is no problem. The second time the application needs it again, I want to check that it is not "nil", which is no problem, and then release it before creating it again in order to get a "fresh" object.

    Now the problem, when trying to release it, the application crashes. The retain count is 1 when trying to release it, so I guess I am not over-releasing it? Here's the code.

    Code:
    if(gameBoardViewController == nil){
    		gameBoardViewController = [[BoardViewController alloc] init];
    	} else {
    		NSLog(@"Retain count %i ", [gameBoardViewController retainCount]);
    		[gameBoardViewController release];
    		gameBoardViewController = [[BoardViewController alloc] init];
    	}
    
    Before, I did initiate it using initWithNibName, but it was the same problem. I removed it since the view is actually loaded in the controllers loadView. I think I have misunderstood something relating to how to work with the nibs, so perhaps this is part of the problem. I am having the same problem in different places. The UIViewController has outlets that is linked in IB to the view loaded from the nib.

    Thanks in advance!
     
  2. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #2
    I think that alloc and init-ing a whole new view controller is going to be less efficient that just creating a new method that "resets" the view controller to some "default" state.

    Code:
    if(gameBoardViewController == nil)
    {
        gameBoardViewController = [[BoardViewController alloc] init];
    }
    else
    {
        [gameBoardViewController resetToDefaultState];
    }
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    What do you do with your view controller once it's created? Nav Bar? Something else?

    What's the stack trace for the crash?
     
  4. Nicsoft thread starter macrumors member

    Joined:
    Oct 17, 2009
    Location:
    Stockholm
    #4
    Thanks' for your answers!

    It's a custom controller that handles the board (the view) of a tile-kind-of-game. Actually, it handles the most logic of the entire game. Loading this nib should be the starting point each time the user wants to play the game.

    This is the first iPhone/Ojbective-C app I am doing, hence some learning is coming at the end (only fixing memroy leaks in order to finish the application). If I can find a way of loading the view again, everything is reset. I agree with North Bronson that it's a better way to reset the game each time the user wants to play again, but since this wasn't planned for it would be much easier to load it again. Actually, this is what I did before, but the problem when doing this is memory leaks and that's what I am trying to prevent now by releasing it before I load it again...

    The crash log (I don't understand how to read it in order to get some useful info...). Do you need the "Binary Image" part as well?:

    Process: BlockPop [35978]
    Path: /Users/Niklas/Library/Application Support/iPhone Simulator/User/Applications/D2B62B57-3366-4EE4-8208-AE513E766A35/BlockPop.app/BlockPop
    Identifier: BlockPop
    Version: ??? (???)
    Code Type: X86 (Native)
    Parent Process: launchd [74]

    Date/Time: 2009-12-28 20:35:45.866 +0100
    OS Version: Mac OS X 10.6.2 (10C540)
    Report Version: 6

    Exception Type: EXC_BAD_ACCESS (SIGBUS)
    Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000001
    Crashed Thread: 0 Dispatch queue: com.apple.main-thread

    Application Specific Information:
    objc_msgSend() selector name: release
    iPhone Simulator 3.1 (139.1), iPhone OS 3.1.2 (7D11)

    Thread 0 Crashed: Dispatch queue: com.apple.main-thread
    0 libobjc.A.dylib 0x93fe2edb objc_msgSend + 27
    1 BlockPop 0x00004916 -[BlockPopViewController displayView:] + 201 (BlockPopViewController.m:401)
    2 BlockPop 0x000039ae -[BlockPopViewController playAgain] + 130 (BlockPopViewController.m:197)
    3 UIKit 0x002aa459 -[UIApplication sendAction:to:from:forEvent:] + 119
    4 UIKit 0x0030dba2 -[UIControl sendAction:to:forEvent:] + 67
    5 UIKit 0x0030fdc3 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 478
    6 UIKit 0x0030eb0f -[UIControl touchesEnded:withEvent:] + 442
    7 UIKit 0x002c3e33 -[UIWindow _sendTouchesForEvent:] + 507
    8 UIKit 0x002ad81c -[UIApplication sendEvent:] + 400
    9 UIKit 0x002b40b5 _UIApplicationHandleEvent + 5048
    10 GraphicsServices 0x023b9ed1 PurpleEventCallback + 1533
    11 CoreFoundation 0x01bccb80 CFRunLoopRunSpecific + 3888
    12 CoreFoundation 0x01bcbc48 CFRunLoopRunInMode + 88
    13 GraphicsServices 0x023b878d GSEventRunModal + 217
    14 GraphicsServices 0x023b8852 GSEventRun + 115
    15 UIKit 0x002b5003 UIApplicationMain + 1157
    16 BlockPop 0x00002c18 main + 102 (main.m:14)
    17 BlockPop 0x00002b86 start + 54

    Thread 1:
    0 libSystem.B.dylib 0x98e348da mach_msg_trap + 10
    1 libSystem.B.dylib 0x98e35047 mach_msg + 68
    2 CoreFoundation 0x01bcc382 CFRunLoopRunSpecific + 1842
    3 CoreFoundation 0x01bcbc48 CFRunLoopRunInMode + 88
    4 WebCore 0x025ce803 RunWebThread(void*) + 467
    5 libSystem.B.dylib 0x98e61fbd _pthread_start + 345
    6 libSystem.B.dylib 0x98e61e42 thread_start + 34

    Thread 0 crashed with X86 Thread State (32-bit):
    eax: 0x03923800 ebx: 0x000074dd ecx: 0x9286f0c4 edx: 0x03923bd4
    edi: 0x00000001 esi: 0x0402cc00 ebp: 0xbfffdec8 esp: 0xbfffde94
    ss: 0x0000001f efl: 0x00010206 eip: 0x93fe2edb cs: 0x00000017
    ds: 0x0000001f es: 0x0000001f fs: 0x00000000 gs: 0x00000037
    cr2: 0x00000001
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    You don't really answer my first question. How do you make the view of the view controller visible?

    Crashes in objc_msgSend are usually caused by messaging an object that has already been released.

    Is it possible that you are releasing the view controller from inside its own code? You may be releasing it twice.
     
  6. Nicsoft thread starter macrumors member

    Joined:
    Oct 17, 2009
    Location:
    Stockholm
    #6
    This comment helped me on the right track. I did over-release a couple of objects inside my view controller. Not the actual view controller itself, other objects. And there is a noticible reduction in memory leaks now :) Thank you!

    Still, perhaps you can help me complete this thread by answering this questions, I think I am doing something wrong and don't know what side-effects it may have.

    In loadView of the view controller I load the view nib (named BoardView, a custom view associated with a view in IB with the same name). I have an outlet that is linked to the view itself (done in IB). Directly after the code I presented in my initial post, I also do :

    Code:
    [gameBoardViewController setBPVC:self];
    	
    [self.view addSubview:gameBoardViewController.view];
    The last row in the code above in combination with that I am loading the BoardView in the controller's loadView method doesn't "feel" right, feels like I am in some way doing the same thing twice. It's working so I didn't change it, but perhaps it's becoming a problem in some way? And to be honest, I don't know which part that actually makes the view appear... If I remove the loading of the nib XOR the the last row above it wont work.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    View controllers can automatically load a nib. I don't know why you would load a nib containing the view controller's view in loadView.

    I assume that your app has no navbar and no tabbar. This makes your code responsible for adding and removing views from the view hierarchy.

    I'm guessing that you are trying to control this process from the view controller. IMO, you should either have the view controller only reset its visible properties for a new game or you should control this process from your app delegate. The app delegate can add/remove the appropriate views from the window or from some subview of the window and it can create/release the view controller that manages the game.

    Alternatively you could write a class that is similar to the navigationcontroller or tabbarcontroller classes that does the creation of view controllers and adding/removing their views from the window.
     
  8. Nicsoft thread starter macrumors member

    Joined:
    Oct 17, 2009
    Location:
    Stockholm
    #8
    I think I did solve it...

    This is what I did:

    1. Move all initial logic such as loading nibs and adding images to viewDidLoad instead. I guess loadView is triggered at some point, hence, the iterative calls to loadView?

    2. Do not load the BoardView at all anywhere. The view is loaded automatically, guess because I have an outlet that is associated with the view. But the other nibs I still need to load, don't understand why there is a difference between the nibs, why can I skip loading some but not others?

    At least, I don't do things twice anymore. Where can I read about all this?
     
  9. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #9
  10. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #10
    UINavigationController and UITabBarController know a lot of things about how to connect UIViewControllers to the system and how to correctly display views. Many new developers want to write games and don't want the appearances that those two classes provide. As a result they develop apps that don't have a correct structure because it is a complex task to add and remove views from the screen. In part this is Apple's fault for not providing another class that would allow adding and removing views and view controllers in a simple way.

    It is possible to use a navigation controller without it being visible. If at all possible new developers should go this route.
     
  11. Nicsoft thread starter macrumors member

    Joined:
    Oct 17, 2009
    Location:
    Stockholm
    #11
    Ok, I will have to look into this for next app, this one is more or less finished now.

    Dejo, I have read it, I guess I have to get back to it again, but I may have learned a couple of details since I did this post so I am on track at least.

    Thanks all for the help!
     

Share This Page