iOS 15 上控制台中的消息:“Binding<String> 操作尝试每帧更新多次。”

Bar*_*uik 6 xcode swiftui ios15

我有以下代码:

struct Credential: Equatable {
    var username = ""
    var password = ""
}

enum Database {
    static var credential = Credential()
}

struct UsernamePasswordInput: View {
    @Binding var credential: Credential

    var body: some View {
        Group {
            TextField("Username", text: self.$credential.username)
            SecureField("password", text: self.$credential.password)
        }
        .textFieldStyle(RoundedBorderTextFieldStyle())
    }
}

struct Login: View {
    private var credential: Binding<Credential>

    var body: some View {
        UsernamePasswordInput(credential: self.credential)
    }

    init() {
        self.credential = Binding<Credential>(
            get: {
                Database.credential
            }, set: { newValue in
                Database.credential = newValue
            }
        )
    }
}

struct ContentView: View {
    var body: some View {
        Login()
    }
}
Run Code Online (Sandbox Code Playgroud)

当您在 iOS 15 设备上从 Xcode 13.0 运行此代码时,该消息Binding<String> action tried to update multiple times per frame.将显示在 Xcode 控制台中。TextField每当您在或 中键入字符时就会发生这种情况SecureField。该消息不会出现在 iOS 13 或 14 设备上。

我知道我可以通过使用 a 来解决它,@StateObject但上面的代码反映了一个更大项目的结构。我的问题是:Xcode 消息是否表明存在问题?上面的代码基本上是不正确的吗?

Asp*_*eri 5

这是一个可能的安全解决方法 - 对每个文本字段使用内联分隔绑定:

struct UsernamePasswordInput: View {
    @Binding var credential: Credential

    var body: some View {
        Group {
            TextField("Username", text: Binding(
                get: { credential.username },
                set: { credential.username = $0 }
                ))
            SecureField("password", text: Binding(
                get: { credential.password },
                set: { credential.password = $0 }
                ))
        }
        .textFieldStyle(RoundedBorderTextFieldStyle())
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 Xcode 13 / iOS 15 进行测试