尝试在解除分配时加载视图控制器的视图... UIAlertController

Posted

技术标签:

【中文标题】尝试在解除分配时加载视图控制器的视图... UIAlertController【英文标题】:Attempting to load the view of a view controller while it is deallocating ... UIAlertController 【发布时间】:2015-09-21 20:38:50 【问题描述】:

我正在使用 Xcode 7.0 的发行版进行构建。没有故事板,只有 nib 文件。

我有一个由应用程序委托创建的UINavigationController,并使用视图控制器对其进行初始化。

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];

使用以下命令导航到新视图后:

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

然后返回使用:

[self.navigationController popViewControllerAnimated:YES];

我收到以下错误:

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

虽然我在应用程序中使用了UIAlertControllers,但在收到此错误之前没有使用或实例化。这仅在 ios 9.0 下运行时发生。在 iOS 8.4 下运行不会产生错误。在所有情况下,应用似乎都可以正常运行,并且导航似乎可以正常工作。

我怀疑该错误具有误导性,但我该如何解决这个问题?

根据@Nick,这里是使用的 dealloc 方法:

- (void)deregisterNotificationHandlers 
    [[NSNotificationCenter defaultCenter] removeObserver:self];


- (void)dealloc 
    [self deregisterNotificationHandlers];

【问题讨论】:

我强烈怀疑您在某处使用 UIAlertController 并且没有意识到并且不打算这样做。在你呈现 UIAlertControllers 的地方设置断点,看看会发生什么 我在 + [UIAlertController alertControllerWithTitle:message:preferredStyle:] 上设置了一个断点,但没有。后来我确实创建了一个警报,断点确实起作用了。 您是否在任何地方覆盖dealloc?你能发布更多代码吗? 许多类都有一个 dealloc 方法来从通知中注销。我会在上面添加。 完全跑题了,但是...如果您的所有方法-deregisterNotificationHandlers 所做的只是调用+[NSNotificationCenter removeObserver:],也许您可​​以直接在-dealloc 中执行此操作并删除多余的方法... 【参考方案1】:

我的UIViewController 也有同样的问题,我只是在我的类let alert = UIAlertView() 中声明变量而没有使用它,它在类内的所有函数中都没有作为变量。通过删除它可以解决问题。因此,如果您在没有使用它或在类变量中定义了来自 UIAlertViewUIAlertViewController 的警报,请检查您的班级!

【讨论】:

谢谢,但我没有 UIAlertViewUIAlertViewController 的类变量。 @picciano,再次检查您在视图加载之前定义的位置或其他什么...此消息是由此引起的!尝试搜索抛出项目并禁用您使用的任何警报!几天前我遇到了这个错误,我知道它是怎么回事!当您将控制器推送到声明警报的位置时会发生这种情况。 谢谢。哇,这违反直觉。我在局部变量中定义了一个 UIAlertView,然后在某些情况下没有显示它。我找不到问题所在,挽救了我的一天;) 在我的情况下,问题是 UIActionSheet 作为实例变量。 +1 @NikitaP ,可能是您在删除视图或视图控制器时显示警报!我建议您获取顶部视图控制器(您会在 *** 中找到),然后在该顶部控制器上显示警报!【参考方案2】:

我终于能够将其追踪到第三方库 Mapbox GL 中的 UIActionSheet 类变量。

我向该开发团队提出了一个问题:https://github.com/mapbox/mapbox-gl-native/issues/2475

@Aaoli 提到将UIAlertView 作为类变量的部分功劳(以及赞成票和赏金)。

【讨论】:

在我的情况下,同样的错误也显示在控制台的视图中包含 Mapbox MGLMapView【参考方案3】:

UIAlertController 遇到了同样的问题。

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

我忘记添加以下行。下面的行解决了这个问题。

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

【讨论】:

【参考方案4】:

我通过将我的一些代码移动到viewDidAppear 解决了这个问题。如果我用UIAlertController,会出现你说的同样的问题,不会显示,我也是这样解决的。

如果这不起作用,请告诉我!

【讨论】:

谢谢,但我没有实例化任何 UIAlertController 实例,但此错误已记录到控制台。 是的,它不仅仅属于UIAlertController。如果将所有视图的初始化代码移至viewDidAppear,会发生什么?【参考方案5】:

在我的例子中,在 Swift 3 中,我在添加操作后错过了下面的代码

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

所以,工作代码如下

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)
     
     

//注意我使用的是样本数组

var items = ["iPhone", "iPad", "Mac"]

【讨论】:

Swift 4 - 使用 - 存在(控制器,动画:真,完成:无)【参考方案6】:

当我尝试在 UIViewController 子类中删除我的视图中的“框架”观察者时,我遇到了同样的问题。我通过将removeObserver 包装在isViewLoaded() 中解决了这个问题。你到底在观察什么?

【讨论】:

谢谢,但我没有使用框架观察者。【参考方案7】:

我遇到了这个问题,因为没有navigationController...想NSLog你的导航控制器也只是为了理智......

【讨论】:

以上是关于尝试在解除分配时加载视图控制器的视图... UIAlertController的主要内容,如果未能解决你的问题,请参考以下文章

BAD_EXC_ACCESS 用于在解除分配时尝试加载视图控制器

不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为

UISearchController - 警告尝试加载视图控制器的视图

解除视图控制器警告

将所有 UIAlertView 对象作为全局对象访问以对其进行通用控制(在解除分配视图控制器后解决警报中的 CRASH)

模态转换后解除分配 SKScene