I've recently re-implemented one of my applications in Swift and am getting crash reports from users where when they transition to a NavigationView, the second of the Navigation links causes an exception, as far as I can tell, before any of my code in that class is executed.
All of the crash logs are consistent...
Thread 0 name:
Thread 0 Crashed:
0 libswiftCore.dylib 0x00000001a35d0a88 bool swift::HeapObjectSideTableEntry::decrementStrong(swift::PerformDeinit)1(unsigned int) + 24 (atomic:1003)
1 LAX Time & Score 0x0000000102bd1378 specialized PenaltyTimesView.init(gameState:) + 156 (PenaltyTimesView.swift:0)
2 LAX Time & Score 0x0000000102bcbf80 closure #1 in closure #1 in ConfigurationView.body.getter + 836 (ConfigurationView.swift:0)
3 SwiftUI 0x00000001a628b958 List.init(content:) + 96 (List.swift:594)
4 LAX Time & Score 0x0000000102bcbb80 closure #1 in ConfigurationView.body.getter + 240 (ConfigurationView.swift:20)
5 SwiftUI 0x00000001a5f90d38 NavigationView.init(content:) + 28 (NavigationView.swift:97)
6 LAX Time & Score 0x0000000102bcc844 body.get + 116 (ConfigurationView.swift:19)
Looking at the disassembly, this (PenaltyTimesView.init(gameState:) + 156) is at a point where malloc is being called, which makes lots of sense with the reference counting being done with HeapObjectSideTableEntry in the Swift code.
I'm not trying to do anything particularly clever here, just initializing the View with an ObservedObject (gameState)
struct PenaltyTimesView: View {
@ObservedObject var gameState: GameState
@State private var selectedPenaltyLength : String
@State private var selectedPenaltyIndex : Int
@State private var separatePenaltyClock : Bool
init(gameState : GameState) {
self.gameState = gameState
selectedPenaltyLength = ""
selectedPenaltyIndex = 0
separatePenaltyClock = gameState.separatePenaltyClock
selectedPenaltyLength = formatSeconds(gameState.penaltyLengths![0])
}...
The outer view is also relatively simple:
struct ConfigurationView: View {
@ObservedObject var gameState: GameState
init(gameState: GameState) {
self.gameState = gameState
UINavigationBar.appearance().backgroundColor = UIColor(white: 0.8, alpha: 0.25)
}
var body: some View {
NavigationView {
List {
NavigationLink(
destination: PeriodLengthView(gameState: gameState),
label: {
Text("Period Lengths")
})
NavigationLink(
destination: PenaltyTimesView(gameState: gameState),
label: {
Text("Penalty Times")
})
NavigationLink(
destination: BackgroundView(gameState: gameState),
label: {
Text("Background")
})...
If somehow gameState were bad, I would have assumed that the first NavigationLink would fail, not the second.
I've been unable to reproduce this with the devices I have at hand, so any insights or suggestions would really be appreciated.
Selecting any option will automatically load the page