swift - 绑定值源已删除
问题描述
出于某种原因,在使用状态(带有数组)并与其值之一绑定时,我得到一个索引超出范围错误。一般来说,向数组添加更多值是没有问题的。但是,当您尝试删除一个值时,您会得到一个索引超出范围的错误。
这是我在自己的项目中遇到的问题的简化版本。
在 SwiftUI 中尝试以下示例。只需按住其中一个圆圈即可尝试删除一个!删除时会出现 Swift 错误:
Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
CustomView
我相信错误来自这样一个事实,即被删除的值受value
. 删除时,视图不再有权访问该值,从而触发越界错误。
import SwiftUI
struct Test: View {
@State var values: [Int] = [0, 1, 1, 1]
var totalBalls: Int {
return values.count
}
var body: some View {
HStack {
Text("\(totalBalls)")
VStack {
ForEach(0..<values.count, id: \.self) { i in
CustomView(value: self.$values[i])
}
.onLongPressGesture {
self.values.removeLast() //this line causes an error!
}
}
}
}
}
struct CustomView: View {
@Binding var value: Int
var body: some View {
ZStack {
Circle()
Text("\(value)").foregroundColor(Color.orange)
}.onTapGesture {
self.value+=1
}
}
}
struct Test_Previews: PreviewProvider {
static var previews: some View {
Test()
}
}
解决方案
在这种情况下有两个原因:恒定的 ForEach,以及直接竞价的刷新赛车。
这是一个修复崩溃并按预期工作的解决方案。使用 Xcode 11.4 / iOS 13.4 测试。
struct TestDeleteLast: View {
@State var values: [Int] = [0, 1, 1, 1]
var totalBalls: Int {
return values.count
}
var body: some View {
HStack {
Text("\(totalBalls)")
VStack {
// use index as id in ForEach
ForEach(Array(values.enumerated()), id: \.0.self) { i, _ in
CustomView(value: Binding( // << use proxy binding !!
get: { self.values[i] },
set: { self.values[i] = $0 }))
}
.onLongPressGesture {
self.values.removeLast()
}
}
}
}
}
推荐阅读
- python - 如何在 python 中使用 *args 进行划分?
- flutter - Flutter 需要两次点击/点击来改变 `ontap` 颜色变化
- python - 如何过滤数据框行并将总和保存在新行中?
- javascript - 我正在尝试制作一个看起来已经完成的图像过滤器,但唯一的是当我加载页面时它是空白的,直到我点击过滤器列表
- c++ - C ++ OpenGL纹理未按应有的方式渲染
- php - 你能在 php 文件中回显 php
- javascript - 本地主机中的 chrome 支持我的 Web 共享 API,但托管我的网站后不支持?
- java - 如何将循环中输入的值调用到Process中,这是一个JAVA SRT程序
- pyqt5 - 具有边框半径属性的 QPushButton 不起作用
- c# - macOS 上的 ML.NET ImageClassification 崩溃