仅在组合框架中第一次调用 send() iOS

send() gets called only for the first time in combine framework iOS

每当我在 TextField 中输入内容时,我都会在使 UITextField 成为发布者后通过 'sink' 运算符获取值。但是,现在我想验证该密码,下面的代码片段涉及 'send()',它仅在第一次调用 validatePassword() 方法时有效。之后 'send()' 不起作用。知道为什么会这样吗?我已经探索 Combine 4-5 天了,这里是要点:
1。出版商、订户和运营商。
2。 ViewModel 中的发布者和 ViewController.
3 中的订阅者。 Send() 用于向订阅者发送值。

一切正常,但第一次后仍未被调用。现在坚持了 3-4 个小时。

这是 ViewController

的代码
            viewModel.passwordValidationResult
                .print("Debugging")
                .sink { completion in
                    
                    switch completion {
    
                    case .finished:
                        print("c")
                        return
                    case .failure(_):
                        print("f")
                        return
                    }
                    
                } receiveValue: { _  in
                    print("v")
                }
                .store(in: &bindings)
        }

这是 ViewModel 的代码

class ViewModel
{
    private var bindings = Set<AnyCancellable>()

    @Published var emailValueChanged: String = String()
    @Published var passwordValueChanged: String = String()
        
    let passwordValidationResult = PassthroughSubject<Void, Error>()
    
    //input
    
    func validatePassword(_ password: String) {
        
        if password.count >= 6 {
            passwordValidationResult.send()
        }
        passwordValidationResult.send(completion: .failure(PasswordError.shortPassword))
    }
}

问题出在这一行:

 passwordValidationResult.send(completion: .failure(PasswordError.shortPassword))

正如代码所说,失败是完成。它结束了管道,它永远不能用于其他任何事情。您的 PassthroughSubject 现在已经死了。这就是无法发送更多值的原因。

问题源于这个错误的选择:

let passwordValidationResult = PassthroughSubject<Void, Error>()

您不希望您的信号是 Void 和 Error,您希望它们是 true 和 false(有效和无效)之类的东西:换句话说,您想要 PassthroughSubject<Bool, Never>。或者,您可以使用专用枚举来代替 Bool,例如 .valid.invalid。或者你可以传递一个 Result 对象,它本身有一个 .success case 和一个 .failure case.

无论如何不要发送完成!您希望能够无限期地继续发送信号,而不是在第一次“失败”后切断自己的联系。