在 Release 构建中调用此函数时应用程序崩溃(对于 Debug 它工作完美)
func crashMe()
{
func crashHelper(str: String) {}
var crashString = "123"
crashString.remove(at: crashString.startIndex)
crashHelper(str: "\(crashString)")
crashString.data(using: .ascii)
}
几乎总是在真实设备上重现,并且经常在 iOS 9 或 10 的模拟器上重现(但不是 100%)
从此函数中删除任何行可防止崩溃
我做错了什么或者可能是 Swift 的一些错误?
它可以在不同的地方崩溃,崩溃日志之一:
0x02194b8a in swift_unknownRelease ()
0x020702c5 in _NSContiguousString.__deallocating_deinit ()
0x024cea26 in String.data(using : String.Encoding, allowLossyConversion : Bool) -> Data? ()
0x0007e04f in specialized AppDelegate.crashMe() -> ()
0x0007c31c in AppDelegate.crashMe() -> () [inlined] ()
最佳答案
这是对我最初答案的更新,尽管它更像是一份调查报告而不是答案。
我能够在 Release build 中的一个简单的 macOS 命令行实用程序中重现该问题。 main.swift
的内容如下。
import Foundation
func crashMe() {
func crashHelper(str: String) {
// print("crashHelper() got \(str)") // line 1
print("In crashHelper()!") // line 2
// var i = 123; i += 321; print("In crashHelper() the int is \(i)") // line 3
}
var crashString = "123"
crashString.remove(at: crashString.startIndex)
crashHelper(str: "\(crashString)")
// if let stringData = crashString.data(using: .ascii) {
// print("stringData has \(stringData.count) bytes")
// }
}
crashMe()
print("Success!!!")
一些观察:
- 当调用
crashMe()
时,崩溃始终发生在swift_unknownRetain
中。 - 如果
crashHelper()
中的第 2 行被注释掉,即函数主体为空,则必须取消注释if
block 才能导致崩溃,这现在发生在crashString.data()
调用中。 - 如果第 1 行和/或第 3 行未注释,则无论第 2 行是否存在,程序都不会崩溃。
crashHelper()
不必在另一个函数中定义;它可以是顶级函数,但将其放入函数中会更容易发生崩溃。- 将不带字符串插值的
crashString
传递给crashHelper()
将解决上述崩溃问题。
因此我会说这是字符串插值实现方式中的一个 Swift 错误。
关于ios - 将 Swift 字符串转换为数据时出现 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42567077/