views:

2262

answers:

6

Hi,

I'm bumping into this problem where my application gets EXC_BAD_ACCESS error and stucks/stops. I'm using "Rotate Left" & "Rotate Right" options of simulator to simulate the orientation change behavior. What can be the possible reasons for this error? Since I'm not getting details about the error, I can't trace it.

All my controller classes have:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);    // Return YES for supported orientations
}

Any ideas, pointers? Thanks.

A: 

Set a breakpoint on -[UIDevice setOrientation:] and step through your code in the debugger.

To make debugging easier, you can type call (void)instrumentObjcMessageSends(YES) right in the debugger console to begin logging objc_msgSends to /tmp/, then continue execution and it will trace all the messages that are sent right up until the crash.

rpetrich
A: 

But my code does not have a call to [UIDevice setOrientation:] method.

This is the trace that i get in debug window:

objc_msgSend
-[UIWindow _handleDeviceOrientationChange:]
_nsnote_callback
__CFXNotificationPost
_CFXNotificationPostNotification
-[NSNotificationCenter postNotificationName:object:userInfo:]
-[UIDevice setOrientation:]
-[UIApplication handleEvent:withNewEvent:]
_[UIApplication sendEvent:]
_UIApplicationHandleEvent 
SendEvent
PurpleEventTimerCallBack
CFRunLoopRunSpecific
CFRunLookRunInMode
GSEventRunModel
GSEventRun
-[UIApplication _run]
UIApplicationMain
main

Note that the error appears when my view contains a tab bar. Since no one is replying, i guess this is not a common problem, and i cannot find any resource addressing this issue.

Can i somehow tell my application to run in single orientation (portrait), and don't send events for orientation change.? This might solve my problem, but this is the alternate that i'm looking for.

Mustafa
+2  A: 

It's not uncommon to crash in system library code due to something you didn't set up quite right. This might be that your UIWindow or its content view or your view controller instance was not retained or got released somehow.

That shouldrotate method won't help if your controller isn't still around.

rpetrich's suggestions may still be useful to identify which object got released.

For particularly thorny problems, you could add release, retain, and dealloc methods (that log and call super) to a suspect class of yours and see what's releasing it. Log the -retaincount to keep track (I only use this for diagnostic purposes, not to do memory management in a shipping app).

A: 

Thanks Paul, your comment was helpful, and i was able to fix the problem but with the cost of retaining memory for the view i don't need. Here's whats happening:

I have a view (View A) which opens another view (View B). App Delegate method is responsible for opening both View A and View B. Application does not crashes on View A. I remove View A from window, and release it's controller object, and add View B to the window. I believe this is where i'm doing something wrong. Can you help me out with the code?

Here's the code for releasing View A and opening View B:

- (void)openViewB {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES];

    // Remove viewControllerA from the window's view
    [window removeFromSuperview];

    // !-- Commenting out this block fixes the issue --!
    // Release memory wired for viewControllerA view
    if(viewControllerA) {
     [viewControllerA release];
     viewControllerA = nil;
    }  

    // We call window:addSubView to add the viewB to the main window. 
    // You can use this call to add other views as child views not only to windows
    // but to other views as well. (UIWindow is a subclass of UIView).
    [window addSubview:viewControllerB.view];
    [UIView commitAnimations];

    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

I started the application with tab bar application template, and viewControllerB is of type UITabBarController. I'm definitely doing something wrong here. Any pointers?

Mustafa
A: 

I too faced the same problem, I think if the viewcontroller is released using [ViewController release] but still using the view and by that time if you the change the orientation the application crashes.

You have to figure out exactly when should you release the viewcontroller[propably at exit].

A: 

Why are you calling [window removeFromSuperview]? Shouldn't you be calling [viewControllerA.view removeFromSuperview]?

Mark Smith
i think it works both ways!
Mustafa
Sorry if I'm being dense, but your comment above it says "// Remove viewControllerA from the window's view". [window removeFromSuperview] would remove the window from *its* superview. How does that remove viewControllerA's view from the window?
Mark Smith