绑定 ObservableObject 数组的元素:不推荐使用“下标(_:)" [英] Binding an element of an array of an ObservableObject : 'subscript(_:)' is deprecated

查看:22
本文介绍了绑定 ObservableObject 数组的元素:不推荐使用“下标(_:)"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 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 中,BindingMutableCollection 的一致性已被其他内容取代.它不再遵循 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆