绑定 ObservableObject 数组的元素:不推荐使用“下标(_:)" [英] Binding an element of an array of an ObservableObject : 'subscript(_:)' is deprecated
问题描述
我使用的是 ObservableObject 'DataStore',它包含一个对象数组('exampleList')('exampleObject').
I'm using an ObservableObject 'DataStore', which contains an array ('exampleList') of objects ('exampleObject').
@Published exampleList = [exampleObject]()
我通过@EnvironmentObject ('dataStore') 调用 DataStore.
I'm calling the DataStore via @EnvironmentObject ('dataStore').
@EnvironmentObject var dataStore = DataStore()
然后我用
ForEach(0..<dataStore.exampleList.count) { index in ....
要将 item 的元素绑定到详细信息视图,我这样做:
To bind element of item to a detail view, I'm doing like this:
DetailView(itemBinding: $dataStore.exampleList[index])
直到 Xcode11 beta 4,它才完美运行.从 XCode11 beta 5 开始,它仍然有效,但 Xcode 给了我这个警报:
Until Xcode11 beta 4, it worked perfectly. Since XCode11 beta 5, it still works but Xcode gives me this alert:
'subscript(_:)' 已弃用:有关迁移路径,请参阅发行说明
'subscript(_:)' is deprecated: See Release Notes for a migration path
我尝试使用更简单的东西,使用一个包含字符串数组的简单 @State var,这是同样的问题:调用该数组的元素时,并尝试将该值用于 TextField:
I tried with simpler stuff, with a simple @State var containing an array of strings, and it's the same issue: when calling an element of this array, and trying to use the value into a TextField:
TextField("test", text: $test[0])
我收到了同样的警报.
我不明白如何解决它.这是否意味着我们不再可以在数组中绑定值?那么,我们如何迭代一个数组并绑定一个特定的项目?
I don't understand how to fix it. Does that mean that we no longer can bind values inside an array? Then, how can we iterate an array and bind a specific item?
这是我关于 Stack Overflow 的第一个问题,如果我的问题很笨拙,我深表歉意...非常感谢您的回答,我多年来一直在使用 Stack Overflow,这太棒了,我总能找到现有且有用的答案,但这是我第一次找不到任何答案,这就是我问的原因.
This is my first question on Stack Overflow, I apologize if my question is clumsy... Thanks a lot for your answers, I'm using Stack Overflow for years, it's amazing, I always find existing and helpful answers, but it is the first time I can't find any, that's why I'm asking.
推荐答案
Xcode 11, beta 6 更新:
好消息!正如我所怀疑的那样,在 beta 6 中,Binding
与 MutableCollection
的一致性已被其他内容取代.它不再遵循 MutableCollection,而是让您通过 @dynamicMemberLookup
访问元素.结果是您现在可以继续执行 $text[3]
并且不再收到警告!看来这个问题现在可以关闭了.
Good news! Just as I suspected, in beta 6, the Binding
conformance to MutableCollection
has been been replaced with something else. Instead of conforming to MutableCollection, it now let your access the elements via @dynamicMemberLookup
. The result is you now can keep doing $text[3]
and no longer get a warning! It seems this question can be closed now.
Xcode 11,beta 5.旧答案:
我终于有时间对此进行了一些调查.正如我在评论中提到的,我认为等到 Collection
一致性完全删除(或替换为其他内容)是明智的.但为了满足我们的好奇心,我创建了一个关于 Binding
的扩展,我认为它可以满足当前的 Collection
一致性.唯一的区别是,我没有通过下标访问,而是实现了一个名为 element(_ idx: Int)
的函数来获取元素的 Binding
.
I finally got some time to investigate this a little. As I mentioned in the comments, I think it would be wise to wait until the Collection
conformance is completely removed (or replaced with something else). But just to satisfy our curiosity, I have created an extension on Binding
, that I think does what the current Collection
conformance does. The only difference is that, instead of accessing through a subscript, I implemented a function called element(_ idx: Int)
to get a Binding<T>
to the element.
如果有一天完全删除了一致性,我可能会更改实现,并自己遵守Collection
.我现在不能这样做,因为它会与现有(和已弃用)的实现相冲突.目前,我认为这演示了如果您绝对想摆脱警告,如何处理它们.
If one day the conformance is completely removed, I may change the implementation, and conform to Collection
myself. I cannot do it now, because it would conflict with the existent (and deprecated) implementation. For the time being, I think this demonstrate how to handle the warnings if you absolutely want to get rid of them.
只是想清楚.我没有使用此代码.只要我仍然可以通过下标访问元素,我仍然会这样做并忽略警告.这仅用于学术目的.
扩展名是:
extension Binding where Value: MutableCollection, Value.Index == Int {
func element(_ idx: Int) -> Binding<Value.Element> {
return Binding<Value.Element>(
get: {
return self.wrappedValue[idx]
}, set: { (value: Value.Element) -> () in
self.wrappedValue[idx] = value
})
}
}
它可以这样使用:
struct MainView: View {
@Binding var text: [String]
var body: some View {
TextField("", text: $text.element(0))
TextField("", text: $text.element(1))
TextField("", text: $text.element(2))
}
}
这篇关于绑定 ObservableObject 数组的元素:不推荐使用“下标(_:)"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!