dismissModalViewControllerAnimated: (and dismissViewControllerAnimated) crashing in iOS 5
Solution 1
In iOS5 the managing of the lifecyle somehow changed and I cannot explain that issue in detail. Anyway, the fix is to postpone that workflow from applicationDidFinishLaunchingWithOptions to applicationDidBecomeActive. It seems that something isn't initialized right at the call of applicationDidFinishLaunchingWithOptions.
- (void)applicationDidFinishLaunchingWithOptions:... {
// in order to do this only at launching, but not on every activation
// Declaration as property for example
applicationDidLaunch = YES;
}
- (void) applicationDidBecomeActive:(UIApplication *)application {
if (applicationDidLaunch) {
applicationDidLaunch = NO;
[Start your login Workflow with modal view presenting here]
}
}
Curious to ur feedback :)....
Solution 2
I will add my 2 cents : i had ImagePickerController and got its dismissing working only when i did not release the picker manually (IOS 5 SDK).
So. for your case i could offer such workaround : 1. remove line - [loginController release]; 2. to prevent memory leaks add loginController as a property to your current controller and release it only in dealloc() of current controller :
@interface myViewController : UIViewController
@property (nonatomic, retain) LoginController *loginController;
@end
...
@implementation myViewController
- (void)showLoginPanel {
self.loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil];
// ... something goes here
}
-(IBAction)loginClose()
{
// this should close all windows as far as you call it from current (main) controller
[self dismissModalViewControllerAnimated:YES];
// ... then anything you want EXCEPT [loginController release];
}
-(void)dealloc()
{
[loginController release];
}
@end
Good luck :)
P.S. I have just written this so it is just an idea how to cheat it. Somebosy may correct me ... though anyway it worked for me.
Related videos on Youtube
jbcaveman
Updated on June 24, 2022Comments
-
jbcaveman almost 2 years
I can't find any logical explanation, but the fact remains that, in iOS 5 (xCode 4.2), if I presentModalView:* animated:YES, I can call dismissModalViewAnimated:* fine, but if I call presentModalView:* animated:NO, then calling the dismiss method crashes. (This works the same if I use the new presentViewController:animated:completion: + dismissViewControllerAnimated:). I am going TRY to work around this for now (I don't want the presentation animated) and report a bug to Apple, but I have been beating my head on this for a while. Any and all suggestions are welcome. Not much out there on iOS 5, so please help if you can. Sample code that does not crash in iOS 4 or iOS 5:
LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil]; [self presentModalViewController:loginController animated:YES]; [loginController release]; ... [self dismissModalViewControllerAnimated:YES];
This will crash in iOS 5 with EXC_BAD_ACCESS on the dismiss call:
LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil]; [self presentModalViewController:loginController animated:NO]; [loginController release]; ... [self dismissModalViewControllerAnimated:YES]; //crashes with EXC_BAD _ACCESS
One note: I have an animation within the loginController that happens on viewDidLoad. Going to see if taking that out changes anything, but I wanted to get this out there since I need a solution asap.
[Edit] Full code flow... In AppDelegate, application:didFinishLaunchingWithOptions:
if (!loggedIn) [myViewController showLoginPanel];
In myViewController:
- (void)showLoginPanel { LoginController *loginController = [[LoginController alloc] initWithNibName:@"LoginControllerGG" bundle:nil]; if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) { [self presentViewController:loginController animated:NO completion:nil]; } else { [self presentModalViewController:loginController animated:NO]; //iOS 4 works fine with or without animation } [loginController release]; }
In loginController:
- (IBAction)closeLoginWindow { [[NSNotificationCenter defaultCenter] postNotificationName:@"CloseLoginWindow" object:nil]; } //doing it this way because calling on the self.parentViewController doesn't work
Back in myViewController:
- (void) viewDidLoad ... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeLoginWindow) name:@"CloseLoginWindow" object:nil]; ... - (void)closeLoginWindow { if ([self respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) { [self dismissViewControllerAnimated:YES completion:nil]; //iOS 5 crashes only if presentation was not animated } else [self dismissModalViewControllerAnimated:YES]; //deleting the previous condition, iOS 5 still crashes if presentation was not animated }
-
jbcaveman over 12 yearsLooks like I don't have to go through and change all of my presentModalViewController calls to presentViewController calls like I thought. Whew, I can save that for the next release.
-
Rene Berlin over 12 yearsI had the same problem, just moved it to DidBecomeActive and submitted the fix in order to have a bug-free version in the Store... No idea what lifecycle changes Apple did...
-
Admin almost 12 yearsit doesn't help me with : stackoverflow.com/questions/11832981/…
-
Admin almost 12 yearsI have the showLoginPanel on (IBAction) and the login close as a callback, but in main thread, also the logincontroller relase in dealloc only and I have the crach : stackoverflow.com/questions/11832981/…