将Swift String转换为Data时的EXC_BAD_ACCESS

aba*_*mut 6 ios swift3

在Release版本中调用此函数时应用程序崩溃(对于Debug,它运行完美)

func crashMe()
{
    func crashHelper(str: String) {}

    var crashString = "123"
    crashString.remove(at: crashString.startIndex)

    crashHelper(str: "\(crashString)")

    crashString.data(using: .ascii)
}
Run Code Online (Sandbox Code Playgroud)

几乎总是在真实设备上重现,并且通常在模拟器上(但不是100%)使用iOS 9或10

从此函数中删除任何行可防止崩溃

我做错了什么或者是一些Swift bug?

它可能会崩溃在不同的地方,崩溃日志之一:

swift_unknownRelease()中的0x02194b8a

_NSContiguousString .__中的0x020702c5 deallocating_deinit()

String.data中的0x024cea26(使用:String.Encoding,allowLossyConversion:Bool) - >数据?()

0x0007e04f在专门的AppDelegate.crashMe() - >()中

AppDelegate.crashMe()中的0x0007c31c - >()[inlined]()

Ana*_*i P 1

这是对我最初答案的更新,尽管它更多的是调查报告而不是答案。

我能够在发布版本中的简单 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!!!")
Run Code Online (Sandbox Code Playgroud)

一些观察结果:

  • 崩溃总是发生swift_unknownRetaincrashMe() is called.
  • 如果第 2 行crashHelper()被注释掉,即函数有一个空的主体,那么if必须取消注释该块才会发生崩溃,这现在发生在crashString.data()调用时。
  • 如果第 1 行和/或第 3 行未注释,则无论第 2 行是否存在,程序都不会崩溃。
  • crashHelper()不必在另一个函数中定义;它可以是一个顶级函数,但将其放入函数中会更容易崩溃。
  • 不带crashString字符串插值传递 tocrashHelper()将解决上述崩溃问题。

因此我想说这是字符串插值实现方式中的一个 Swift 错误。