简体   繁体   中英

Having trouble with crash when performing .ondelete on a list (SwiftUI).. crashing in .onReceive for a timer

I am having a problem with an app that I am making, that is crashing. I have been trying to hours to figure it out, but am stumped.

I have a list that holds multiple timers, that are all updated with.onReceive.

I have everything working... I can start and stop each timer, reset each timer, etc. However, when I try to use.onDelete on the list to remove a timer, I get a crash with "index out of range" in the.onReceive method.

List {
                ForEach(viewModel.initialTimeRemainingSeconds.indices, id: \.self) { time in
                    Section {
                        HStack {
                            VStack(alignment: .leading) {
                                Text("\(viewModel.foodName[time])")
                                    .font(.title2.weight(.bold))
                                Text("\(viewModel.convertSecondsToTime(timeInSeconds: viewModel.timeRemainingSeconds[time]))")
                                    .font(.title2)
                            }
                            Spacer()
                            Button {
                                viewModel.timeRemainingSeconds[time] = viewModel.initialTimeRemainingSeconds[time]
                            } label: {
                                Image(systemName: "gobackward")
                            }
                            .buttonStyle(PlainButtonStyle())
                            .frame(width: 50, height: 50, alignment: .center)
                            .font(.title2)
                            .foregroundColor(.white)
                            .background(.blue)
                            .cornerRadius(10)
                            Button(viewModel.timerButtonTitle[time]) {
                                viewModel.timerStartAndStop(timerNumber: time)
                            }
                            .buttonStyle(PlainButtonStyle())
                            .frame(width: 100, height: 50, alignment: .center)
                            .font(.title2)
                            .foregroundColor(.white)
                            .background(viewModel.timerButtonColor[time])
                            .cornerRadius(10)
                        }
                        .onReceive(viewModel.timer) { _ in
                            if viewModel.timerStart[time] == true {
                                viewModel.timeRemainingSeconds[time] -= 1
                            }
                        }
                    }
                }
                .onDelete { indexSet in
                    viewModel.deleteItem(indexSet: indexSet)
                }
            }

I have an array of Bools that tells the.onReceive method if the timer should start or stop.

@Published var timerStart = [Bool]()

I tried using a second ForEach inside of the.onReceive method, but that causes a crash where swift takes too long to build... I guess the ForEach happening every call of.onReceive is too much for Xcode.

If I comment out the.onReceive, I can delete without a crash...

Finally figured it out. Had to change timers to scheduled timers instead of published, which allowed me to call.invalidate() on the individual timer before deleting it from the Timer array. The timer was still running for the last tick even after deleting it, giving index out of range. Man that one was a pain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM