"Thread 1: Fatal error: Index out of range" when removing from array with @Binding
"Thread 1: Fatal error: Index out of range" when removing from array with @Binding
我已经 运行 解决了 SwiftUI 中的这个问题。我希望能够在用户按下按钮时从数组中删除一个项目,但是当我尝试时出现“线程 1:致命错误:索引超出范围”错误。这似乎与 IntView 采用 @Binding 的事实有关:如果我使 num
只是一个常规变量,则代码可以正常工作而不会出现错误。不幸的是,出于我的目的,我需要能够将 Binding 传递给视图(这是一个简化的案例),所以我不确定我需要做什么才能使 Binding 不会导致错误。
这是我的代码:
import SwiftUI
struct IntView: View {
@Binding var num: Int // if I make this "var num: Int", there are no bugs
var body: some View {
Text("\(num)")
}
}
struct ArrayBugView: View {
@State var array = Array(0...10)
var body: some View {
ForEach(array.indices, id: \.self) { num in
IntView(num: $array[num])
Button(action: {
self.array.remove(at: num)
}, label: {
Text("remove")
})
}
}
}
非常感谢任何帮助!
在您的代码中,ForEach
与 indicies
和 id: \.self
是错误的。 SwiftUI 中的 ForEach
视图不像传统的 for 循环。 ForEach
的文档指出:
/// It's important that the `id` of a data element doesn't change, unless
/// SwiftUI considers the data element to have been replaced with a new data
/// element that has a new identity.
这意味着我们不能在 ForEach
中使用索引、枚举或新数组。 ForEach
必须位于可识别项的实际数组中。这样 SwiftUI 就可以跟踪移动的行视图,这称为结构标识,您可以在 Demystify SwiftUI WWDC 2021.
中了解它
因此您必须将代码更改为以下内容:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
var num: Int
}
struct IntView: View {
let num: Int
var body: some View {
Text("\(num)")
}
}
struct ArrayView: View {
@State var array: [Item] = [Item(num:0), Item(num:1), Item(num:2)]
var body: some View {
ForEach(array) { item in
IntView(num: item.num)
Button(action: {
if let index = array.firstIndex(where: { [=11=].id == item.id }) {
array.remoteAt(index)
}
}, label: {
Text("remove")
})
}
}
}
我已经 运行 解决了 SwiftUI 中的这个问题。我希望能够在用户按下按钮时从数组中删除一个项目,但是当我尝试时出现“线程 1:致命错误:索引超出范围”错误。这似乎与 IntView 采用 @Binding 的事实有关:如果我使 num
只是一个常规变量,则代码可以正常工作而不会出现错误。不幸的是,出于我的目的,我需要能够将 Binding 传递给视图(这是一个简化的案例),所以我不确定我需要做什么才能使 Binding 不会导致错误。
这是我的代码:
import SwiftUI
struct IntView: View {
@Binding var num: Int // if I make this "var num: Int", there are no bugs
var body: some View {
Text("\(num)")
}
}
struct ArrayBugView: View {
@State var array = Array(0...10)
var body: some View {
ForEach(array.indices, id: \.self) { num in
IntView(num: $array[num])
Button(action: {
self.array.remove(at: num)
}, label: {
Text("remove")
})
}
}
}
非常感谢任何帮助!
在您的代码中,ForEach
与 indicies
和 id: \.self
是错误的。 SwiftUI 中的 ForEach
视图不像传统的 for 循环。 ForEach
的文档指出:
/// It's important that the `id` of a data element doesn't change, unless
/// SwiftUI considers the data element to have been replaced with a new data
/// element that has a new identity.
这意味着我们不能在 ForEach
中使用索引、枚举或新数组。 ForEach
必须位于可识别项的实际数组中。这样 SwiftUI 就可以跟踪移动的行视图,这称为结构标识,您可以在 Demystify SwiftUI WWDC 2021.
因此您必须将代码更改为以下内容:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
var num: Int
}
struct IntView: View {
let num: Int
var body: some View {
Text("\(num)")
}
}
struct ArrayView: View {
@State var array: [Item] = [Item(num:0), Item(num:1), Item(num:2)]
var body: some View {
ForEach(array) { item in
IntView(num: item.num)
Button(action: {
if let index = array.firstIndex(where: { [=11=].id == item.id }) {
array.remoteAt(index)
}
}, label: {
Text("remove")
})
}
}
}