尝试在解除分配时加载视图控制器的视图... 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>)
虽然我在应用程序中使用了UIAlertController
s,但在收到此错误之前没有使用或实例化。这仅在 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()
中声明变量而没有使用它,它在类内的所有函数中都没有作为变量。通过删除它可以解决问题。因此,如果您在没有使用它或在类变量中定义了来自 UIAlertView
或 UIAlertViewController
的警报,请检查您的班级!
【讨论】:
谢谢,但我没有UIAlertView
或 UIAlertViewController
的类变量。
@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)