Attempting to load the view of a view controller while it is deallocating ... UIAlertController

40,953

Solution 1

I was finally able to track it down to a UIActionSheet class variable inside a third-party library, Mapbox GL.

I opened an issue with that dev team: https://github.com/mapbox/mapbox-gl-native/issues/2475

Partial credit (and an up vote and bounty) to @Aaoli for mentioning having a UIAlertView as a class variable.

Solution 2

I had the same issue with my UIViewController where i was only declaring variable in my class let alert = UIAlertView() without using it yet, it was out of all the functions just inside the class as variable. by removing that solves the issue. so please check in your class if you have defined alert from UIAlertView or UIAlertViewController like that without using it or in the class variable!

Solution 3

We had the same issue with UIAlertController.

let alert = UIAlertController(title: "", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: {(action : UIAlertAction!) in
                //some actions
                              } ))

I had forgot adding the following line. Below line solved the problem.

self.presentViewController(alert, animated: true, completion: nil)

Solution 4

I solved this by moving some of my code to viewDidAppear. If I used UIAlertController, it would cause the same problem you mentioned and would not be displayed, and I solved it the same way.

Let me know if that doesn't work!

Solution 5

In my case, in Swift 3, I had missed the code below after adding the action

presentViewController(theAlert, animated: true, completion: nil)

So, the working code is as below

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

     if (editingStyle == UITableViewCellEditingStyle.Delete) {

        let title = "Delete ????"
        let message = "Are you sure you want to delete this item?"

        let theAlert = UIAlertController(title: title,
                                   message: message,
                                   preferredStyle: .ActionSheet)

     let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
     theAlert.addAction(cancelAction)

     let onDelete = UIAlertAction(title: "Delete", style: .Destructive, handler: { (action) -> Void in
     self.items.removeAtIndex(indexPath.row)
     self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

     })
     theAlert.addAction(onDelete)
        presentViewController(theAlert, animated: true, completion: nil)
     }
     }

//Note I was using a sample array

var items = ["iPhone", "iPad", "Mac"]
Share:
40,953
picciano
Author by

picciano

Anthony is a software development and architecture professional with twenty years experience. Anthony has led the development effort for award-winning mobile apps, enterprise-scale infrastructure and applications, database modeling, security architecture and implementation, business process design, and physical computing. Anthony has extensive expertise in both the telecommunications and advertising industries. Anthony has led development teams both in-house and offshore. Anthony has provided in-house training in software development, Internet security, and software design patterns. See my LinkedIn profile for more information. http://www.linkedin.com/in/anthonypicciano

Updated on April 25, 2020

Comments

  • picciano
    picciano about 4 years

    I am building with the release version of Xcode 7.0. No storyboards, just nib files.

    I have a single UINavigationController created by the app delegate and initialize it with a view controller.

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UIViewController *viewController = [[TGMainViewController alloc] initWithNibName:nil bundle:nil];
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    self.navigationController.navigationBar.hidden = YES;
    self.window.rootViewController = self.navigationController;
    [self.window makeKeyAndVisible];
    

    After navigating to a new view using:

    TGRoutePreparationViewController *viewController = [[TGRoutePreparationViewController alloc] initWithNibName:nil bundle:nil];
    [self.navigationController pushViewController:viewController animated:YES];
    

    Then going back using:

    [self.navigationController popViewControllerAnimated:YES];
    

    I receive the following error:

    Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UIAlertController: 0x7b29a600>)
    

    While I do use UIAlertControllers in the app, none are used or instantiated before receiving this error. This only happens when running under iOS 9.0. Running under iOS 8.4 produces no error. In all cases, the app appears to function normally and the navigation appears to be working.

    I suspect the error is misleading, but how can I fix this?

    Per @Nick, here is the dealloc method being used:

    - (void)deregisterNotificationHandlers {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)dealloc {
        [self deregisterNotificationHandlers];
    }
    
  • picciano
    picciano over 8 years
    Thanks, but I have no class variables of UIAlertView or UIAlertViewController.
  • picciano
    picciano over 8 years
    Thanks, but I am not using frame observers.
  • picciano
    picciano over 8 years
    Thanks, but I am not instantiating any UIAlertController instances yet this error is logged to the console.
  • AaoIi
    AaoIi over 8 years
    @picciano, Check again somewhere where your defining before view loads or something... this message is caused by that ! try to search throw the project and disable any alert your using ! i had this error just days ago and i know what its about ! it happens when you push a controller to where the alert is declared.
  • Sheamus
    Sheamus over 8 years
    Yes, it doesn't just pertain to UIAlertController. What happens if you move all your view's initialization code to viewDidAppear?
  • Nazir
    Nazir over 8 years
    In my case also same error shown in console on the view contain Mapbox MGLMapView
  • Laky
    Laky over 8 years
    Thanks. Wow, this is counterintuitive. I defined an UIAlertView in a local variable and then didn't present it in some cases. I couldn't find out what was wrong, saved my day ;)
  • Giorgio
    Giorgio over 8 years
    In my case the problem was an UIActionSheet as instance variable. +1
  • Manuel
    Manuel over 8 years
    In my case it was the 3rd party bundle "Siren" that instantiated a UIAlertController without presenting it.
  • Nikita P
    Nikita P about 8 years
    For me, it's not defined anywhere, I am not using any third party libs. I can't find what's wrong. var message:String? if somthn message = "a" if message { let alert = UIAlertController(title: "Game Over", message: message, preferredStyle: UIAlertControllerStyle.Alert) let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler:nil) alert.addAction(action) self.presentViewController(alert, animated: true, completion: nil)}}
  • AaoIi
    AaoIi about 8 years
    @NikitaP , it might be that you are presenting the alert while removing view or view controller ! I suggest you get top view controller (you will find that in stackoverflow) and then present the alert on that top controller !
  • Nikita P
    Nikita P about 8 years
    @AaoIi Thanks, I found the issue, it was while setting the boolean, I was changing this in between, which was making this call twice, before the first one gets over.
  • Muhammad Ibrahim
    Muhammad Ibrahim over 7 years
    I had forgotten writing the line self.presentViewController(alert, animated: true, completion: nil). Writing it solved the problem. Thanks.
  • Jeremy Andrews
    Jeremy Andrews over 5 years
    Swift 4 - use - present(controller, animated: true, completion: nil)