代码之家  ›  专栏  ›  技术社区  ›  Allen Savio

Swift的combineframework combinelatetest的问题

  •  0
  • Allen Savio  · 技术社区  · 5 年前

    我浏览了WWDC的“介绍Combine”视频,视频中说每当发布者的值被更新时,combineTest就会被调用和更新。但我创建的代码片段工作起来很奇怪。

    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)
        }
    }
    
    

    当我初始化并调用更新发布者“password”的checkSub()函数时,不会调用combineTest。为什么它的行为很奇怪?

    输入:

    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 回复  |  直到 5 年前
        1
  •  2
  •   Sandeep    5 年前

    似乎问题出在内存管理上。这个 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 您将保留只有在对象被释放之后才被释放的cancelable。所以,这应该能正常工作。