为什么不在一个子对象上调用KVO观察者?

问题描述 投票:-1回答:1

使用以下Swift游乐场,为什么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个回答
2
投票

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

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

  • 你允许观察者不再存在。它是通过调用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"
© www.soinside.com 2019 - 2024. All rights reserved.