发布版本中应用程序崩溃,但在调试版本中没有崩溃。

35

正如标题所述,我正在编写一款 iPhone 应用程序。在调试模式下,它运行得很完美,但当我将其构建为发布版本并通过 TestFlight 安装时,它会崩溃。根据崩溃日志,可能与以下代码有关:

let path = NSBundle.mainBundle().pathForResource("PrinterList", ofType: "plist")
if path != nil {
    let printerDic = NSDictionary(contentsOfFile: path!)
    let printerList = NSArray(array: printerDic.allKeys)
    printerNames = printerList as [String]
}

我正在使用来自Brother的框架进行无需AirPrint的打印,但我认为这不是问题的原因,因为应用程序在与框架进行任何操作之前就崩溃了。 它仅在执行这些行的ViewController中崩溃。 我仅需要在此ViewController中使用该框架。


9
如果你关闭Swift编译器在发布版本中的优化,并再次尝试运行,你是否仍然会遇到崩溃?(在构建设置中,找到Swift编译器/代码生成) - Matt Gibson
如果我这样做,就无法通过TestFlight安装它:'Invalid Profile: distribution build entitlements must have get-task-allow set to false.' 但是我试过用iTunes... 编辑:使用iTunes和Xcode无法安装。 - Ben
是的!它成功了!非常感谢。请将您的评论写成答案,以便我可以将其标记为正确答案。 - Ben
请注意,这可能不是真正的答案——在beta版本中,Swift优化中可能存在某种错误,这并不是不可能的,但也有可能是优化版本显示出了您代码中不太明显的错误。这种情况在任何语言中都可能发生... 您尝试过使用Xcode 6 beta 7进行优化发布吗?它刚刚发布;值得一试... - Matt Gibson
1
我的应用程序一直崩溃,看起来可能是一个NSArray的问题,就像你的代码所暗示的那样。应用程序运行得很好,然后在更改数组(在启动时加载)之后,应用程序就会崩溃...在调试中重新构建将打开相同的保存数组。感谢你的问题和修复! - werm098
显示剩余2条评论
4个回答

39

有很多原因会导致应用程序在发布模式下崩溃,但在调试模式下没有崩溃(例如,内存分配差异显示实际上在两个版本中都存在的错误)。即使使用非 beta 版本的编译器/语言进行跟踪,也需要花费大量时间。

你说,如果按照我建议的方式构建发布版本并关闭优化,问题会消失。鉴于 Swift 编译器仍处于测试版本,并且肯定仍然存在偶尔的问题,我曾看到编译器在构建经过优化的版本时会突然崩溃,这可能实际上是优化器的一个 bug。

因此,现在我建议先不要深入研究这个问题。在我们获得编译器的完整版本之前,请先不要开启优化,进行发布。然后,打开优化并检查是否仍有问题。如果仍有问题,那么这就是开始花费精力尝试找出是编译器 bug 还是您自己代码中存在 bug 的时间了。


1
我之前也遇到过类似的问题,我的应用在调试模式下运行良好,但使用Test Flight时崩溃了。但现在我按照您的建议进行更改后,它已经恢复正常了。非常感谢!“如果您关闭Swift编译器对发布版本的优化并再次尝试,是否仍会发生崩溃?(在构建设置中,转到Swift编译器/代码生成)" - Bruno Morais
1
Bug还在那里...非常感谢你,Matt,你救了我的一天!20年编程历史上第一次是由于编译器的问题... - beetree
我的发布版本由于split函数而崩溃了。请查看我的答案:http://stackoverflow.com/questions/29107277/swift-release-build-crashes-unless-i-turn-off-optimization/32361548#32361548 - Mike Taverne
想确认一下是否有人在最新的iOS版本9.3.1中遇到了类似的应用程序崩溃问题?我们发现在iOS9.3中,当将优化级别设置为最大时,会出现此问题,但当将其更改为NONE时,应用程序可以正常工作。如果有人对此有任何其他意见,请告知我们。先感谢您! - Birender Singh
应用程序崩溃问题是由于内存泄漏引起的。优化解决方案对我没有起作用。不确定为什么在调试模式下不会发生这种情况。 - Alex Jin
显示剩余3条评论

9
我曾经遇到过相同的问题。最终我通过开启“整体模块优化”功能来解决它。结合正确实现访问控制,这应该可以解决您的崩溃问题。
苹果公司对于整体模块优化的解释如下:
使用整体模块优化来推断内部声明中的 final 关键字。具有 internal 访问权限的声明(如果没有声明,则为默认值)仅在它们被声明的模块中可见。因为 Swift 通常单独编译组成模块的文件,所以编译器无法确定内部声明是否在不同的文件中被覆盖。但是,如果启用了整体模块优化,整个模块将一次性编译在一起。这使得编译器可以推断整个模块,并在没有可见重写的情况下,在内部声明中推断 final。
您可以在项目设置中启用此选项:
但请注意,此选项会一次性优化目标中的所有文件,以换取更好的性能和更长的编译时间。

谢谢,你救了我的周末。 - kubilay
1
我遇到了一个问题,当编译模式为“整个模块”且优化级别为“优化以提高速度[-O]”时,会出现“MyStruct”的“outlined destroy”崩溃。如果我更改其中一个选项,则崩溃消失,但似乎两者都建议在发布版本中使用。我不知道出了什么问题,也不知道如何捕获它,因为它只会在发布版本中发生。 - Ariel Bogdziewicz

6

为了捕获崩溃,可以在Debug模式下将优化级别设置为最快、最小[-Os],以更接近于在用户设备上生成和运行的代码。

您可以在构建设置中,Swift编译器/代码生成下进行设置。


1

苹果还描述了一个已知的问题。我简要描述一下,以防有人在寻找答案时之前的解决方案不起作用。

检查你的崩溃日志是否存在以下错误:

Dyld Error Message:
  Library not loaded: @rpath/libswiftCore.dylib

or

[....] [deny-mmap] mapped file has no team identifier and is not a platform binary:
/private/var/mobile/Containers/Bundle/Application/5D8FB2F7-1083-4564-94B2-0CB7DC75C9D1/YourAppNameHere.app/Frameworks/libswiftCore.dylib

如果您遇到类似上面的崩溃输出,请按照苹果公司的指南进行操作。

提示:在XCode的Window->Device下,您可以轻松查看日志。点击设备并点击查看设备日志。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接