【问题标题】:Why doesn't KVO observer get called on a sub object?为什么不在子对象上调用 KVO 观察者?
【发布时间】:2018-09-13 20:36:58
【问题描述】:

使用下面的 Swift Playground,为什么 view 内部的观察者永远不会被调用?

import Foundation

@objc class Person: NSObject {
    @objc dynamic var name = "Taylor Swift"
}

let taylor = Person()

taylor.observe(\Person.name, options: .new) { person, change in
    // we do get here
    print("I'm now called \(person.name)")
}

taylor.name = "Justin Bieber"

@objc class View: NSObject {
    var person = Person()

    override init() {
        person.observe(\Person.name, options: .new) { (person, change) in
            // we never get here
            print("I changed my name to \(person.name)")
        }
    }
}

let view = View()
let lewis = Person()
lewis.name = "Lewis"
view.person = lewis
view.person.name = "Lewis"
print(view.person.name)

【问题讨论】:

    标签: swift4 key-value-observing


    【解决方案1】:

    为什么视图内部的观察者永远不会被调用

    有两个原因(即你做错了两件不相关的事情)。

    • 您已允许观察者消失。它通过对observe 的调用返回,但您不会捕获并保留它。所以观察在任何事情发生之前就结束了。 (你在第一次观察时也犯了同样的错误,但是你在操场上跑步的事实掩盖了它。这是为什么操场是魔鬼的工作的另一个例子。)

    • 您替换了其他人 (view.person = lewis)。所以改名的人不是我们观察的人;我们观察的那个人已经不复存在了。

    所以,这次重写将修复它:

    @objc class Person: NSObject {
        @objc dynamic var name = "Taylor Swift"
    }
    
    @objc class View: NSObject {
        var person = Person()
        var ob : NSKeyValueObservation?
    
        override init() {
            super.init()
            self.ob = self.person.observe(\.name, options: .new) { (person, change) in
                print("I changed my name to \(person.name)")
            }
        }
    }
    
    let view = View()
    view.person.name = "Lewis"
    

    【讨论】:

    • 谢谢马特 :) 我清楚地理解了第二点。对于第一点,我没有意识到observe 正在返回一个您必须与person 分开保留的对象。它特别令人困惑,因为当它没有被包裹在一个对象中时它可以工作。无论如何,我真的很感谢你对一个不太好的问题的帮助
    • “这特别令人困惑,因为当它没有被包裹在一个对象中时它可以工作”但这只是因为你在操场上进行测试。在真实的世界中没有“它没有被包裹在一个物体中”这样的事情
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2012-03-03
    • 2014-02-05
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多