toupper
toupper

Reputation: 636

Crash presenting modal view controller

I have this crash. It is similar to other threads, but not the same. I would like to show a modal view controller first the user goes to a specific view controller. Following the hints, I do that on - (void) viewDidAppear:(BOOL)animated, and apply a delay as I saw it's recommended.

 - (void) viewDidAppear:(BOOL)animated 
    {
      [super viewDidAppear:animated];
       [self performSelector:@selector(presentMyModal) withObject:nil afterDelay:1];
    }



     - (void) presentModal{
    ModalViewController *modal = [[[ModalViewController alloc] init] autorelease];
    [self presentModalViewController:modal animated:YES];   
   }

Afterwards, ramdomly It crashes. I get this message in console:

<Warning>: *** Assertion failure in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:], /SourceCache/UIKit/UIKit-1447.6.4/UIWindowController.m:186
Thu Feb  3 10:00:44 unknown MyApp[1830] <Error>: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from <UINavigationController: 0x454260> to <ModalViewController: 0x47af00> while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'
    *** Call stack at first throw:
    (
        0   CoreFoundation                      0x3759dc7b __exceptionPreprocess + 114
        1   libobjc.A.dylib                     0x32d9bee8 objc_exception_throw + 40
        2   CoreFoundation                      0x3759dac3 +[NSException raise:format:arguments:] + 70
        3   Foundation                          0x351a3e73 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 62
        4   UIKit                               0x359e92a8 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 208
        5   UIKit                               0x359e8c98 -[UIViewController presentModalViewController:withTransition:] + 2792
        6   UIKit                               0x35a7b51c -[UIViewController _tryRecursivelyPresentModalViewController:withTransition:] + 116
        7   UIKit                               0x359e84c0 -[UIViewController presentModalViewController:withTransition:] + 784
        8   UIKit                               0x359e8060 -[UIViewController presentModalViewController:animated:] + 96
        9   MyApp                         0x0005d57f -[MyAppViewController presentMyModal] + 58
        10  Foundation                          0x351724db __NSFireDelayedPerform + 366
        11  CoreFoundation                      0x37552305 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 16
        12  CoreFoundation                      0x37551cd9 __CFRunLoopDoTimer + 988
        13  CoreFoundation                      0x37521a91 __CFRunLoopRun + 1184
        14  CoreFoundation                      0x3752150b CFRunLoopRunSpecific + 226
        15  CoreFoundation                      0x37521419 CFRunLoopRunInMode + 60
        16  GraphicsServices                    0x33e76d24 GSEventRunModal + 196
        17  UIKit                               0x3591d57c -[UIApplication _run] + 588
        18  UIKit                               0x3591a558 UIApplicationMain + 972
        19  MyApp                         0x0000e75f main + 50
        20  MyApp                         0x0000e6e8 start + 52

As you can see, I wait until view is appeared. Is this maybe an OS bug? It seems like it tries to present recursively other modal view controllers, provoquing crashes. Thanks a lot.

Upvotes: 3

Views: 5034

Answers (2)

aksommerville
aksommerville

Reputation: 358

Our preferred solution is to use -[UIViewController presentViewController:animated:completion:] and do whatever the next action is (eg presenting another VC) in the completion block.

For example:

[self presentViewController:yourViewController animated:YES completion:^{
    [yourViewController presentMyModal];
}];

This method was introduced in iOS 5.0.

Upvotes: 0

Mayjak
Mayjak

Reputation: 1497

Apart from me being picky in the comment, I thought I could as well help with this one as well. I think you need to search for the culprit somewhere else. I created a new project and a view controller with this snippet:

#import "VC1.h"


@implementation VC1

- (void) viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self performSelector:@selector(presentModal) withObject:nil afterDelay:1.0];
}

- (void)presentModal {
  static int colorChooser = 0;
  VC1 *vc1 = [[[VC1 alloc] init] autorelease];
  switch (colorChooser%2) {
    case 0:
      vc1.view.backgroundColor = [UIColor whiteColor];
      break;
    default:
      vc1.view.backgroundColor = [UIColor blackColor];
      break;
  }
  colorChooser++;
  [self presentModalViewController:vc1 animated:YES];
}

@end

And it works flawlessly after being pushed on the navigation controller. It is recursively alternating between black and white views, tested both in the sim and on a 3G device.

Maybe you are doing some other view transitions due to some notifications or other asynchronic means? Either way you would need to share more of your code for anyone to tell where the problem is.

Upvotes: 0

Related Questions