Fabricにこのスタックトレースがあります。
私の質問:クラッシュログから、関数 'formatMessageAuthorName'がこのEXC_BREAKPOINTクラッシュの唯一の原因ですか?たとえば、この関数内のコードとは別に、クラッシュの原因として他に考えられるものはありますか?
ここに私のformatMessageAuthorName関数があります:
private static func formatMessageAuthorName(firstname: String, lastname: String?=nil) -> String {
// Capitalise first character of firstname
var Cap_firstname = firstname
Cap_firstname.replaceRange(Cap_firstname.startIndex...Cap_firstname.startIndex, with: String(Cap_firstname[Cap_firstname.startIndex]).capitalizedString)
guard let lastname = lastname else { return Cap_firstname }
// if has lastname & first char, capitalise too and concat with firstname.
if let firstCharLastName = lastname.characters.first {
return "\(Cap_firstname) \(String(firstCharLastName).uppercaseString)."
} else {
return firstname
}
}
私の仮定
関数がクラッシュすることを知っている唯一の手がかりは、「firstname」が空の文字列の場合です。無効な配列インデックスにアクセスするため、ここでクラッシュします。
String(Cap_firstname[Cap_firstname.startIndex])
ただし、「firstname」は空ではない(サーバーから取得される)と確信しているため、この仮定についてはまだ懐疑的です。クラッシュしたユーザーアカウントにログインし、そのページ(MessageViewController)を使用してでもテストしましたが、クラッシュしたことはなく、firstnameは正しく表示されました。また、iOS 8、9、10からクラッシュを受け取ったため、iOSバージョンに関するものではないようです。
私は最近のアプリの更新後にこのクラッシュをたくさん(> 300)持っていますが、なぜそれが前に起こらないのか、ここのコードは更新によって変更されず、影響を受けるユーザーでそれを再現することはできません。
犯人がこの関数のコードのみであり、他の可能性(マルチスレッド、レルムなど)がない場合、代わりに「firstname」が空の文字列である可能性があるなど、サーバーの問題に焦点を当てることができます。しかし、それでも、それらのユーザーアカウントを既に使用しており、これがクラッシュすることはないため、どのように発生するか想像できません。
どうもありがとう。
EXC_BREAKPOINTは、何らかのソート(*)のトラップ命令を実行することによって常にトリガーされ、例外はトラップ命令を実行したスレッドに直接配信されます。したがって、このスタックを持つこのスレッドがEXC_BREAKPOINTを取得したというクラッシュレポートが表示されている場合、それはスレッドが実際にトラップ命令を実行したことを行ったことを意味します。
おそらくバイナリのクラッシュアドレスを調べることでこれを確認できます。何らかのトラップ命令が表示されます。 Swift標準ライブラリは、トラップ命令を使用して、さまざまな種類の無効なアクセスエラーを通知し、そのコードはおそらくクラッシュする関数にインライン化されました。これは上記の例の意味があります。
(*)EXC_BREAKPOINTはデータウォッチにも使用できますが、それはここで起こっていることではなく、とにかくウォッチデータにアクセスしたスレッドに配信されます...