38

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
  • 22,341
  • 9
  • 69
  • 82
  • 1
    I strongly suspect that you are using a UIAlertController somewhere and don't realise it and don't intend to. Set breakpoints where you present UIAlertControllers and see what happens – Paulw11 Sep 21 '15 at 20:49
  • I had a breakpoint set on + [UIAlertController alertControllerWithTitle:message:preferredStyle:] and there were none. I did later create an alert and the breakpoint did work. – picciano Sep 21 '15 at 21:08
  • do you override `dealloc` anywhere? can you post more code? – Nick Sep 21 '15 at 21:23
  • Many of the classes have a dealloc method to deregister from notifications. I'll add that above. – picciano Sep 21 '15 at 21:28
  • Hey, I'm encounting this situation now. Did u fix this problem already? how? – ronan Sep 22 '15 at 07:12
  • @ronan i wish, but no, still unresolved. vote this question up and i'll add a bounty tomorrow – picciano Sep 22 '15 at 16:18
  • same error here... And I don't have any UIAlertController instantiated... – Gerardo Sep 23 '15 at 16:45
  • 1
    Totally off topic, but... If all your method `-deregisterNotificationHandlers` does is just call `+[NSNotificationCenter removeObserver:]`, perhaps you can do that directly in `-dealloc` and cut a superfluous method... – Nicolas Miari Sep 24 '15 at 01:15
  • Are you assigning a `UIAlertViewController` to a property of the view controller? If so, in the alert's action handlers, do you happen to have any strong references which should really be weak? – unspokenblabber Sep 24 '15 at 21:26
  • @unspokenblabber I do not – picciano Sep 24 '15 at 22:27
  • @picciano Can you check whether your references are strong where they should be? Could something be released too quickly? – Rainer Schwarze Sep 27 '15 at 12:44
  • Also seeing this same issue – Crake Sep 30 '15 at 20:03
  • Will this cause app review to reject? What about for testflight? – Max Phillips Feb 22 '16 at 00:39
  • I was also experiencing this without having any `UIAlertControllers` in my application. However, my push was being initiated by resuming user activity via `application:continueUserActivity:restorationHandler:` in my AppDelegate. I had not overriden `application:willContinueUserActivityWithType:`; according to [this post](http://stackoverflow.com/a/34821417/5513562), this can lead to `UIAlertControllers` being shown, and hence the error message. Overriding the `application:willContinueUserActivityWithType:` function solves the problem for me. – Andrew Bennet May 28 '16 at 15:54

7 Answers7

47

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!

AaoIi
  • 8,288
  • 6
  • 45
  • 87
  • 1
    Thanks, but I have no class variables of `UIAlertView` or `UIAlertViewController`. – picciano Sep 30 '15 at 23:10
  • @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. – AaoIi Sep 30 '15 at 23:33
  • 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 ;) – Laky Dec 15 '15 at 23:55
  • 1
    In my case the problem was an UIActionSheet as instance variable. +1 – Giorgio Dec 28 '15 at 10:02
  • In my case it was the 3rd party bundle "Siren" that instantiated a UIAlertController without presenting it. – Manuel Feb 06 '16 at 15:32
  • 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)}}` – Nikita P Feb 25 '16 at 01:25
  • 1
    @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 ! – AaoIi Feb 25 '16 at 14:42
  • @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. – Nikita P Feb 25 '16 at 18:39
  • I had forgotten writing the line `self.presentViewController(alert, animated: true, completion: nil)`. Writing it solved the problem. Thanks. – Muhammad Ibrahim Aug 27 '16 at 06:22
6

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.

picciano
  • 22,341
  • 9
  • 69
  • 82
5

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)
Photon Point
  • 798
  • 2
  • 13
  • 23
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!

Sheamus
  • 6,506
  • 3
  • 35
  • 61
  • Thanks, but I am not instantiating any `UIAlertController` instances yet this error is logged to the console. – picciano Sep 30 '15 at 23:12
  • Yes, it doesn't just pertain to `UIAlertController`. What happens if you move all your view's initialization code to `viewDidAppear`? – Sheamus Sep 30 '15 at 23:43
1

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"]
Naishta
  • 11,885
  • 4
  • 72
  • 54
0

I had the same issue, when I tried to remove a "frame" observer on my view in a UIViewController subclass. I solved this issue by wrapping the removeObserver in a isViewLoaded(). What exactly are you observing?

fruitcoder
  • 1,073
  • 8
  • 24
0

I had this problem by not having a navigationController... I know it sounds obvious but jumping about in various projects this one didn't have a UINavigationControllerto hand.... so others coming here you might want to NSLog your nav controller just for sanity too...

Magoo
  • 2,552
  • 1
  • 23
  • 43