当前位置: 首页 > 面试题库 >

在视图中删除绑定对象时出现“致命错误:索引超出范围”

欧阳鸿德
2023-03-14
问题内容

在修改子视图依赖于绑定对象的数组时,我在避免索引超出范围错误时遇到了一些麻烦。

我有一个称为WorkoutList的父视图。WorkoutList具有ActiveWorkoutStore的EnvironmentObject。ActiveWorkoutStore是一个ObservableObject,它具有Workout对象的数组。我有一个从ActiveWorkoutStore检索的积极锻炼的列表。我正在使用ForEach循环来处理这些活动锻炼的索引,并将html" target="_blank">对象绑定传递到称为EditWorkout的子视图,作为NavigationLink的目标。EditWorkout具有完成锻炼的按钮,该按钮会将其从ActiveWorkoutStore的锻炼阵列中删除,并将其添加到WorkoutHistoryStore。我从ActiveWorkoutStore的activeWorkouts数组中删除该对象时遇到麻烦,立即导致索引超出范围错误。我怀疑这是因为活动视图依赖于我刚刚删除的绑定对象。一世’
ve尝试了几种排列方式,包括将锻炼传递给EditWorkout,然后使用其ID引用ActiveWorkoutStore中的锻炼来执行我的操作,但遇到了类似的麻烦。我在网上看到了很多示例,这些示例遵循这种利用ForEach遍历索引的模式,并且据我所知,我已经对其进行了镜像,但是我怀疑我可能会错过这种方法的细微差别。

我在下面附加了代码示例。让我知道您是否有任何疑问,或者我还有什么需要补充的!在此先感谢您的帮助!

import SwiftUI

struct WorkoutList: View {
    @EnvironmentObject var activeWorkoutsStore: ActiveWorkoutStore
    @State private var addExercise = false
    @State private var workoutInProgress = false

    var newWorkoutButton: some View {
        Button(action: {
            self.activeWorkoutsStore.newActiveWorkout()
        }) {
            Text("New Workout")
            Image(systemName: "plus.circle")
        }
    }

    var body: some View {
        NavigationView {
            Group {
                if activeWorkoutsStore.activeWorkouts.isEmpty {
                    Text("No active workouts")
                } else {
                    List {
                        ForEach(activeWorkoutsStore.activeWorkouts.indices.reversed(), id: \.self) { activeWorkoutIndex in
                            NavigationLink(destination: EditWorkout(activeWorkout: self.$activeWorkoutsStore.activeWorkouts[activeWorkoutIndex])) {
                                Text(self.activeWorkoutsStore.activeWorkouts[activeWorkoutIndex].id.uuidString)
                            }
                        }
                    }
                }
            }
            .navigationBarTitle(Text("Active Workouts"))
            .navigationBarItems(trailing: newWorkoutButton)
        }
    }
}

EditWorkout(子视图)

//
//  EditWorkout.swift
//  workout-planner
//
//  Created by Dominic Minischetti III on 11/2/19.
//  Copyright © 2019 Dominic Minischetti. All rights reserved.
//

import SwiftUI

struct EditWorkout: View {
    @EnvironmentObject var workoutHistoryStore: WorkoutHistoryStore
    @EnvironmentObject var activeWorkoutStore: ActiveWorkoutStore
    @EnvironmentObject var exerciseStore: ExerciseStore
    @Environment(\.presentationMode) var presentationMode
    @State private var addExercise = false
    @Binding var activeWorkout: Workout

    var currentDayOfWeek: String {
        let weekdayIndex = Calendar.current.component(.weekday, from: Date())
        return Calendar.current.weekdaySymbols[weekdayIndex - 1]
    }

    var chooseExercisesButton: some View {
        Button (action: {
            self.addExercise = true
        }) {
            HStack {
                Image(systemName: "plus.square")
                Text("Choose Exercises")
            }
        }
        .sheet(isPresented: self.$addExercise) {
            AddWorkoutExercise(exercises: self.$activeWorkout.exercises)
                .environmentObject(self.exerciseStore)

        }
    }

    var saveButton: some View {
        Button(action: {
            self.workoutHistoryStore.addWorkout(workout: self.$activeWorkout.wrappedValue)
            self.activeWorkoutStore.removeActiveWorkout(workout: self.$activeWorkout.wrappedValue)
            self.presentationMode.wrappedValue.dismiss()
        }) {
            Text("Finish Workout")
        }
        .disabled(self.$activeWorkout.wrappedValue.exercises.isEmpty)
    }

    var body: some View {
        Form {
            Section(footer: Text("Choose which exercises are part of this workout")) {
                chooseExercisesButton
            }
            Section(header: Text("Exercises")) {
                if $activeWorkout.wrappedValue.exercises.isEmpty {
                    Text("No exercises")
                } else {
                    ForEach(activeWorkout.exercises.indices, id: \.self) { exerciseIndex in
                        NavigationLink(destination: EditWorkoutExercise(exercise: self.$activeWorkout.exercises[exerciseIndex])) {
                            VStack(alignment: .leading) {
                                Text(self.activeWorkout.exercises[exerciseIndex].name)
                                Text("\(self.activeWorkout.exercises[exerciseIndex].sets.count) Set\(self.activeWorkout.exercises[exerciseIndex].sets.count == 1 ? "" : "s")")
                                    .font(.footnote)
                                    .opacity(0.5)
                            }
                        }
                    }
                    saveButton
                }
            }
        }
        .navigationBarTitle(Text("Edit Workout"), displayMode: .inline )
    }
}

ActiveWorkoutStore

import Foundation
import Combine

class ActiveWorkoutStore: ObservableObject {
    @Published var activeWorkouts: [Workout] = []

    func newActiveWorkout() {
        activeWorkouts.append(Workout())
    }

    func saveActiveWorkout(workout: Workout) {
        let workoutIndex = activeWorkouts.firstIndex(where: { $0.id == workout.id })!

        activeWorkouts[workoutIndex] = workout
    }

    func removeActiveWorkout(workout: Workout) {
        if let workoutIndex = activeWorkouts.firstIndex(where: { $0.id == workout.id }) {
            activeWorkouts.remove(at: workoutIndex)
        }
    }
}

锻炼

import SwiftUI

struct Workout: Hashable, Codable, Identifiable {
    var id = UUID()
    var date = Date()
    var exercises: [WorkoutExercise] = []
}

问题答案:

ForEach<Range> 是常量范围容器(请注意下面的构造函数说明),构造后不允许对其进行修改。

>     extension ForEach where Data == Range<Int>, ID == Int, Content : View {
>  
>         /// Creates an instance that computes views on demand over a
> *constant*
>         /// range.
>         ///
>         /// This instance only reads the initial value of `data` and so it
> does not
>         /// need to identify views across updates.
>         ///
>         /// To compute views on demand over a dynamic range use
>         /// `ForEach(_:id:content:)`.
>         public init(_ data: Range<Int>, @ViewBuilder content: @escaping
> (Int) -> Content)
>     }

如果要修改容器,则必须使用 ForEach(activeWorkout.exercises)



 类似资料:
  • 问题内容: 我的函数中不断出现此错误 我正在尝试读取数组answerRecord中的值。我使用一个全局变量arrayCount,它跟踪im当前指向哪个索引。 我在较早的函数中做了一个println,它为var arrayCount返回一个整数1的值,因此arrayCount不为空。因此,它应该能够将数组解释为: *假设arrayCount现在为1 answerRecord [arrayCount]

  • 在com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191)在com.microsoft.sqlserver.jdbc.SQLServerPrearedStatement.setterGetParam(SQLServerPrearedStatement.java:9

  • 错误 ()1中的索引器错误回溯(最近一次调用)---- ~/Documents/PhD/IntelliSys19/journal/ColdStart_实验/相似性_函数。用户中u2的装饰矩阵中的py()145:146评级1=np。nan_to_num(np.array(user_ratings_matrix.iloc[u1-1].values))-- ~/anaconda3/lib/python3

  • 我已经使用创建了“CfnUserPool”对象https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_cognito/CfnUserPool.html aws文件。 我想获取UserPool的“Pool Id”。其Id值为“us-east-1_4kxxxxxx”。我使用python尝试了很多选项来获取这个值,但都没有成功。 所以我

  • 我试着运行这个: 但是得到这个错误: 回溯(最后一次调用): 文件“C:\Users\Shakh\Desktop\Hello3.py”,第4行,在 打印(“Hallo”,sys.argv[1]) 索引器:列表索引超出范围

  • 我使用带有AnyLogic的外部数据库来检查数据库中是否存在数据。如果没有,那么我需要插入并执行另一个操作。然而,我得到了这个错误 jdbc。SQLServerException:索引1超出范围。 这是我的代码。 下面是完整的错误消息