在更新到Xcode 6.3(beta 1)和Swift 1.2之后,我的所有应用程序都只在发布版本中神秘地崩溃。在Debug版本中更新我的Swift 1.2代码后,它们工作正常。调试器没有发现发生崩溃的地方,并不清楚原因。一些崩溃是
malloc:***对象0x7ff0c3824800错误:未释放指针被释放***在malloc_error_break中设置断点以进行调试
其他人是"无法识别的选择器",但它们毫无意义;选择器被发送到的对象甚至不是我知道使用的对象。看来内存管理出了问题,所以一个对象正在替换另一个对象。
究竟是什么造成这种情况?在调用堆栈中没有任何用处(因此我甚至不知道我的代码中发生崩溃的位置)并且当我单步执行代码时,调试器的变量窗格中没有变量显示(这样我就可以&# 39;甚至看看事物的价值观,我怎么能开始追踪它呢?
答案 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版本中运行。