我观看了WWDC的“ Incomducing Combine”视频,其中有人说,每当发布者的值更新时,就会调用并更新CombineLatest。但是我创建的摘录效果很奇怪。
class Mango {
var enableButton = false
@Published var userName = "admin"
@Published var password = "poweruser"
@Published var passwordAgain = "poweruser"
var validatePassword: AnyCancellable {
Publishers.CombineLatest($password, $passwordAgain).map { (password, reenterpass) -> String? in
print("Is Password Same to \(password)? :", password == reenterpass)
guard password == reenterpass else { return nil }
return password
}.eraseToAnyPublisher()
.map { (str) -> Bool in
print("In Map", str != nil)
guard str != nil else { return false }
return true
}.assign(to: \.enableButton, on: self)
}
init() {
validatePassword
}
func checkSub() {
print("1. Is password same? ->",enableButton)
password = "nopoweruser"
print("2. Is password same? ->",enableButton)
}
}
当我初始化并调用函数checkSub()时,发布者的“密码”已更新,不会调用CombineLatest。为什么表现奇怪?
输入:
let mango = Mango()<br>
mango.checkSub()
输出:
Is Password Same to poweruser? : true
In Map true
1. Is password same? -> true
2. Is password same? -> true
答案 0 :(得分:2)
似乎问题出在内存管理上。 validatePassword
可取消状态会自动发布,这意味着该订阅在创建后就立即完成,因为您没有保留它。使用lazy var
使其成为属性而不是计算属性,它应该可以正常工作。
lazy var validatePassword: AnyCancellable = {
Publishers.CombineLatest($password, $passwordAgain).map { (password, reenterpass) -> String? in
print("Is Password Same to \(password)? :", password == reenterpass)
guard password == reenterpass else { return nil }
return password
}.eraseToAnyPublisher()
.map { (str) -> Bool in
print("In Map", str != nil)
guard str != nil else { return false }
return true
}.assign(to: \.enableButton, on: self)
}()
使用lazy
,您将保留可取消对象,该对象仅在对象释放后才能释放。因此,这应该可以正常工作。