Swift 1.2中的神秘崩溃 - 仅在版本中构建

时间:2015-02-14 03:27:06

标签: xcode debugging swift

在更新到Xcode 6.3(beta 1)和Swift 1.2之后,我的所有应用程序都只在发布版本中神秘地崩溃。在Debug版本中更新我的Swift 1.2代码后,它们工作正常。调试器没有发现发生崩溃的地方,并不清楚原因。一些崩溃是

  

malloc:***对象0x7ff0c3824800错误:未释放指针被释放***在malloc_error_break中设置断点以进行调试

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

究竟是什么造成这种情况?在调用堆栈中没有任何用处(因此我甚至不知道我的代码中发生崩溃的位置)并且当我单步执行代码时,调试器的变量窗格中没有变量显示(这样我就可以&# 39;甚至看看事物的价值观,我怎么能开始追踪它呢?

1 个答案:

答案 0 :(得分:12)

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

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中崩溃 - 这证明了我的理论认为这是内存管理的问题。

隔离了代码后,我能够尝试各种替代方案。很明显问题是属性var terms : [Term](因为Swift在dealloc引擎盖下做的唯一事情是释放这个数组)。正如您在init中看到的,此属性的值是来自Cocoa(通过sortedArrayUsingDescriptors)的NSArray,并且已经转换为Swift数组。通过反复试验,我发现:

  • 如果我们更改实现以使属性为NSArray(请参阅注释掉的替代行),我们不会崩溃。

  • 或者,如果我们不排序(这样的NSArray不是来自Cocoa),我们就不会崩溃。

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

但是第三种替代是一种解决方法。我在我的所有应用中查看了as! [SomeType]演员表中的所有代码,并用as NSArray as [SomeType]替换了所有代码,并且我的所有崩溃都消失了!

我的理论是,在优化的Release版本中,Swift的内存管理出现问题只是在非常具体的情况下,NSArray从Cocoa到达,并且在我们的代码可以保持之前被我们桥接到[AnyObject]它的。这样的NSArray没有正确地过桥。但是通过转换为NSArray然后返回到特定的[SomeType] Swift数组,问题就解决了。

当然,我认为当苹果公司解决这个问题时,他们会修复它,然后我们就可以停止使用这种解决方法了。但在此之前,我的应用程序再次在Release版本中运行。