2017-03-02 74 views
6

應用程序崩潰時調用該函數在發佈版(用於調試它的作品完美無瑕)EXC_BAD_ACCESS當斯威夫特字符串轉換爲數據

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

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

    crashHelper(str: "\(crashString)") 

    crashString.data(using: .ascii) 
} 

幾乎總是再現真實設備並經常在模擬器(但不是100%)的無論是iOS的9或10

從這個功能刪除任何行可防止碰撞

,該怎麼辦錯了或者也許是一些斯威夫特錯誤?

它可以在不同的地方墜毀,墜毀日誌之一:

0x02194b8a在swift_unknownRelease()

0x020702c5在_NSContiguousString .__ deallocating_deinit()

在String.data 0x024cea26(使用: String.Encoding,allowLossyConversion:Bool) - > Data? ()

0x0007e04f專門AppDelegate.crashMe() - >()

0x0007c31c在AppDelegate.crashMe() - >()[內嵌]()

+0

更新的問題描述,請嘗試在真實的設備上 – abagmut

+0

你有沒有崩潰日誌? – Larme

+0

增加了其中一個 – abagmut

回答

1

這是一個更新我的最初的答案,儘管它更像是一份調查報告而不是答案。

我能夠在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!!!") 

一些觀察:

  • 崩潰一貫發生在swift_unknownRetaincrashMe()被調用。
  • 如果crashHelper()中的第2行被註釋掉了,即該函數有一個空的主體,那麼if塊必須取消註釋才能發生崩潰,現在發生在crashString.data()調用中。
  • 如果第1行和/或第3行未註釋,則程序不會崩潰,而不管第2行是否存在。
  • crashHelper()不必在另一個函數內部定義;它可以是頂層函數,但將其放入函數會使崩潰更可能發生。
  • 通過crashString沒有字符串插值到crashHelper()將解決上述崩潰。

因此,我會說這是一個Swift錯誤如何實現字符串插值。

+0

這是一個最小的崩潰版本:'func crashHelper(str:String){}; var crashString =「123」; crashString.remove(at:crashString.startIndex); crashHelper(str:「\(crashString)」); print(「成功!!!」)'如果你註釋掉'print'行,不會崩潰;我真的不明白這一點。 – matt

相關問題