gpt4 book ai didi

swiftui - ForEach - 索引超出范围?

转载 作者:行者123 更新时间:2023-12-05 08:29:40 24 4
gpt4 key购买 nike

为什么运行此代码会显示“ fatal error :索引超出范围”?

import SwiftUI

struct MyData {
var numbers = [Int](repeating: 0, count: 5)
}

@main
struct TrySwiftApp: App {
@State var myData = MyData()

var body: some Scene {
WindowGroup {
ChildView(myData: myData)
.frame(width: 100, height: 100)
.onAppear {
myData.numbers.removeFirst() // change myData
}
}
}
}

struct ChildView: View {
let myData: MyData // a constant

var body: some View {
ForEach(myData.numbers.indices) {
Text("\(myData.numbers[$0])") // Thread 1: Fatal error: Index out of range
}
}
}

检查其他问题后,我知道我可以通过以下方式修复它

// fix 1: add id
ForEach(myData.numbers.indices, id: \.self) {
//...
}

// Edited:
//
// This is not a fix, see George's reply
//
// fix 2: make ChildView conforms to Equatable
struct ChildView: View, Equatable {
static func == (lhs: ChildView, rhs: ChildView) -> Bool {
rhs.myData.numbers == rhs.myData.numbers
}

...

我的问题:
常数值(由 let 定义)如何不同步?
ForEach 到底做了什么?

最佳答案

让我给你一个简单的例子来告诉你发生了什么:

struct ContentView: View {

@State private var lowerBound: Int = 0

var body: some View {

ForEach(lowerBound..<11) { index in
Text(String(describing: index))
}

Button("update") { lowerBound = 5 }.padding()

}

}

如果您查看上面的代码,您会发现我正在使用这样的范围初始化 ForEach:lowerBound..<11这意味着这个 0..<11 ,当你这样做时,你是在告诉 SwiftUI,嘿,这是我的范围,它不会改变!这是一个恒定的范围! SwiftUI 说可以!如果您不打算更新上限或下限,则可以使用 ForEach 而无需显示或给出 id !但是如果你再次看到我的代码!我正在更新 ForEach 的 lowerBound 并且通过此操作我打破了关于恒定范围的协议(protocol)!所以 SwiftUI 来告诉我们,如果你要更新我的 ForEach 范围计数或任何东西,那么你必须使用 id然后你可以更新给定的范围!原因是因为如果我们有 2 个具有相同值的相同项目,SwiftUI 将无法知道你说的是哪一个!使用 id我们正在解决 SwiftUI 的识别问题!关于 id 你可以这样使用它:id:\.self或者像这样 id:\.customID如果您的结构符合 Hash-able 协议(protocol),或者在最后一种情况下,如果您将结构符合可识别协议(protocol),则可以停止使用 id!然后 ForEach 会神奇地沉入其中。

现在看到编辑后的代码,它将构建并运行,因为我们解决了识别问题:

struct ContentView: View {

@State private var lowerBound: Int = 0

var body: some View {

ForEach(lowerBound..<11, id:\.self) { index in
Text(String(describing: index))
}

Button("update") { lowerBound = 5 }.padding()

}

}

关于swiftui - ForEach - 索引超出范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69080476/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com