Swift 1.2中的神秘崩溃 - 仅在版本中构建 [英] Mysterious crashes in Swift 1.2 - in Release builds only

查看:112
本文介绍了Swift 1.2中的神秘崩溃 - 仅在版本中构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在更新到Xcode 6.3(beta 1)和Swift 1.2之后,我所有的应用程序在发布版本中都是神秘地崩溃 。在更新Swift 1.2的代码之后,在Debug版本中,它们工作正常。调试器不会发生发生崩溃的情况,而且不清楚为什么。一些崩溃是

After updating to Xcode 6.3 (beta 1) and Swift 1.2, all my apps are mysteriously crashing in Release builds only. They work fine, after updating my code for Swift 1.2, in Debug builds. The debugger gives no sense of where the crashes are occurring, and it isn't clear why. Some of the crashes are


malloc:***对象0x7ff0c3824800的错误:被释放的指针未分配***设置断点malloc_error_break调试

malloc: *** error for object 0x7ff0c3824800: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

其他是无法识别的选择器,但它们没有任何意义;选择器发送的对象甚至不是我知道使用的对象。看来内存管理出了问题,所以一个对象被替换为另一个对象。

Others are "unrecognized selector", but they make no sense; the objects to which the selectors are being sent are not even objects I'm aware of using. It appears that something has gone wrong with memory management, so that one object is being substituted for another.

可能导致这一点?在调用堆栈中没有什么用(所以我甚至不知道我的代码在哪里发生崩溃),当我执行代码时,没有变量显示在调试器的变量窗格中(这样我甚至不能

What on earth could be causing this? With nothing useful in the call stack (so that I don't even know where in my code the crash occurs) and no variables showing up in the variables pane of the debugger when I step through my code (so that I can't even look at the values of things), how could I even begin to track it down?

推荐答案

令人惊讶的是,我已经做了跟踪这一点,主要是通过删除大型色板中的代码,直到我只是这样(这是一个视图控制器):

Amazingly, I did track this down, mostly by deleting code in large swatches until I was down to just this (it's a view controller):

class LessonListController: UIViewController {
    var terms : [Term]
    // var terms : NSArray
    init(terms data:NSArray) {
        let arr = data.sortedArrayUsingDescriptors([NSSortDescriptor(key: "lessonSection", ascending: true)])
        self.terms = arr as! [Term]
        // self.terms = arr
        super.init(nibName:"LessonList", bundle:nil)
    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    @IBAction func doDismiss(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

如果(在发布版本中)查看控制器,然后关闭它,我们在dealloc中崩溃了,这证明了我的理论,这是内存管理的一个问题。

If (in a Release build) we present this view controller and then dismiss it, we crash on dismiss - in dealloc, which proves my theory that it's a problem with memory management.

隔离代码后,我能够尝试各种替代品。很明显,问题是属性 var terms:[Term] (因为Swift在 dealloc 正在释放这个数组)。这个属性的值可以在我的 init 中看到,它是一个来自Cocoa的NSArray(通过 sortedArrayUsingDescriptors ),并被转换为Swift数组。通过反复尝试,我发现:

Having isolated the code, I was able to try various alternatives. It is clear that the problem is the property var terms : [Term] (because the only thing Swift is doing under the hood in dealloc is releasing this array). The value of this property, as you can see in my init, is an NSArray that has come from Cocoa (thru sortedArrayUsingDescriptors) and has been cast to a Swift array. By trial and error, I discovered:


  • 如果我们更改实现,以使该属性是NSArray(请参阅commented-我们不会崩溃。

  • If we change the implementation so that the property is an NSArray (see the commented-out alternative lines), we don't crash.

或者,如果我们不排序(所以这个NSArray不是来自可可)我们不会崩溃。

Or, if we don't sort (so that this NSArray doesn't come from Cocoa), we don't crash.

或(等待它),如果我们将 self.terms = arr替换为! [Term] with self.terms = arr as NSArray as! [Term] ,我们不会崩溃!

Or (wait for it), if we replace self.terms = arr as! [Term] with self.terms = arr as NSArray as! [Term], we don't crash!

但是第三个选择>是一种解决方法。我在所有我的应用程序中查找了所有我的代码,寻找作为! [SomeType] 转换并将它们全部用替换为NSArray作为[SomeType] ,并且所有我的崩溃都消失了! >

But that third alternative is a workaround. I went through all my code in all my apps looking for as! [SomeType] casts and replaced them all with as NSArray as [SomeType], and all my crashes went away!!

我的理论是,Swift的内存管理在优化的发布版本中出现问题,只是在NSArray从Cocoa到达并为我们桥接的特定情况下到一个 [AnyObject] 之前,我们的代码可以抓住它。这样的NSArray没有正确地穿过桥。但是通过转换为NSArray,然后回到特定的 [SomeType] Swift数组,问题解决了。

My theory is that something is going wrong with Swift's memory management in the optimized Release build just in the very specific situation where an NSArray arrives from Cocoa and is bridged for us to an [AnyObject] before our code can get hold of it. Such an NSArray is not crossing the bridge properly. But by casting to NSArray and then back to down to the specific [SomeType] Swift array, the problem is solved.

当然,我认为当苹果公司指出这一点时,他们会解决这个问题,然后我们可以停止使用这个解决方法。但直到那时,我的应用程序再次在一个Release版本中运行。

Naturally, I assume that when Apple figures this out, they'll fix it and then we can stop using this workaround. But until then, my apps are running in a Release build once again.

这篇关于Swift 1.2中的神秘崩溃 - 仅在版本中构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆