dismissViewControllerAnimated:completion: 导致内存崩溃

Posted

技术标签:

【中文标题】dismissViewControllerAnimated:completion: 导致内存崩溃【英文标题】:dismissViewControllerAnimated:completion: causing memory crash 【发布时间】:2014-07-16 21:47:10 【问题描述】:

所以我正在开发一个应用程序,如果我没有存储在应用程序默认值中的用户名,我会从基本视图启动登录视图。

let defaults = NSUserDefaults.standardUserDefaults()
if !defaults.objectForKey("username") 
    dispatch_async(dispatch_get_main_queue(), 
        self.navigationController.tabBarController.performSegueWithIdentifier("Login", sender: self)
    )

代码在我的故事板中触发“Present Modally”(ios 8)segue,它显示了一个带有默认动画的表单。

它创建的视图具有使用 AutoLayout 排列的各种子视图。

现在,稍后在我的代码中(检查登录是否有效并更新默认设置后)我关闭登录视图。

defaults.setObject(signInData["username"], forKey: "username")
defaults.setObject(signInData["password"], forKey: "password")
defaults.synchronize()
dispatch_async(dispatch_get_main_queue(), 
    self.dismissViewControllerAnimated(true, completion: nil)
)

我在应用程序中遇到了崩溃。具体来说,错误消息(启用僵尸对象时)是

-[_UILayoutGuide superview]: message sent to deallocated instance 0x7fb3cc93bdb0

其中 UILayoutGuide 显然与 AutoLayout 相关。

现在看来,我的视图在被解除后被解除分配,但尽管如此,仍有一个指向它的指针被保留。不过我不确定如何修复它,因为它不在我编写的任何代码中(我认为),而是在 AutoLayout 系统本身中。

【问题讨论】:

能否在崩溃时添加堆栈跟踪? 【参考方案1】:

_UILayoutGuide 是对象的类,0x7fb3cc93bdb0 是对象的旧 RAM 位置(现在是僵尸对象的位置。)“superview”是发送给僵尸对象的消息。

由于您是在 Beta-2 发布之前发布的,其中一个更新是否解决了您的问题?

【讨论】:

【参考方案2】:

我遇到了这个问题,我的应用程序崩溃了,因为在弹出(或关闭)视图控制器后某些视图约束仍然处于活动状态,以下是错误代码。经过一段时间的调试,我发现视图约束被绑定到底部或顶部视图布局,这是崩溃的主要原因,所以我已经将该约束(从布局视图到父视图)更改为父视图查看快照。

由于未捕获的异常“NSGenericException”而终止应用程序,原因:“无法在视图上安装约束。约束是否引用了视图子树之外的内容?那是违法的。约束:视图:>'

【讨论】:

以上是关于dismissViewControllerAnimated:completion: 导致内存崩溃的主要内容,如果未能解决你的问题,请参考以下文章

dismissViewControllerAnimated:completion: 导致内存崩溃

在当前动画完成之前开始dismissViewControllerAnimated

调用了dismissViewControllerAnimated,但没有解除ViewController

状态恢复后,dismissViewControllerAnimated 没有使用相同的动画

dismissViewControllerAnimated() 不会关闭视图控制器

dismissViewControllerAnimated:completion: 方法替换在 Xcode4.6.1 上不起作用