标题有点令人困惑,但它几乎说明了一切。我想在属性的属性上有一个属性观察者:
class A {
var b: B
init() {
b = B()
}
func foo() { }
}
class B {
var c = 0
fun bar() { }
}
var a = A()
在此示例中,为了说明我想要的内容,我希望在设置a.foo()
时调用a.b.c
。如果我想改为呼叫a.b.bar()
,可以通过更改
var c = 0
到
var c = 0 {
didSet {
bar()
}
}
然而,我想要做的事情并没有简单的方法来实施。这是我能想到的唯一可行方式:
class A {
var b: B {
didSet {
b.a = self
}
}
init() {
b = B()
b.a = self
}
func foo() { }
}
class B {
weak var a: A?
var c = 0 {
didSet {
a?.foo()
}
}
}
这似乎是一个非常混乱的解决方案,似乎应该有一个更好的解决方案。谢谢你的帮助。
答案 0 :(得分:1)
最干净的解决方案是让A
派生自NSObject
,以便它可以使用键值观察:
class A: NSObject {
var b: B
override init() {
b = B()
super.init()
self.addObserver(self, forKeyPath: "b.c", options: [.New], context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "b.c" {
foo()
}
}
func foo() {
print("b.c. has changed")
}
}
class B: SKSpriteNode {
// Remember to mark it dynamic here
dynamic var c = 0
func bar() { }
}
var a = A()
a.b.c = 42 // will trigger a.foo()
如果您不想这样,请使用delegate
模式:
protocol BDelegate {
func foo()
}
class A: BDelegate {
var b: B
init() {
b = B()
b.delegate = self
}
func foo() {
print("b.c. has changed")
}
}
class B: SKSpriteNode {
var delegate: BDelegate?
var c = 0 {
didSet {
delegate?.foo()
}
}
func bar() { }
}
var a = A()
a.b.c = 42 // will trigger a.foo()