swift中财产的财产观察员
标题有点让人困惑,但它几乎说明了一切。我希望在一个属性的属性上有一个属性观察员:swift中财产的财产观察员,swift,Swift,标题有点让人困惑,但它几乎说明了一切。我希望在一个属性的属性上有一个属性观察员: class A { var b: B init() { b = B() } func foo() { } } class B { var c = 0 fun bar() { } } var a = A() 在本例中,为了说明我想要什么,我希望在设置a.b.c时调用a.foo()。如果我想调用a.b.bar(),可以通过更改 va
class A {
var b: B
init() {
b = B()
}
func foo() { }
}
class B {
var c = 0
fun bar() { }
}
var a = A()
在本例中,为了说明我想要什么,我希望在设置a.b.c
时调用a.foo()
。如果我想调用a.b.bar()
,可以通过更改
var c = 0
到
然而,我想做的事情并没有简单的实现方法。这是我能想到的唯一能让我随心所欲的方式:
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()
}
}
}
这似乎是一个非常混乱的解决方案,似乎应该有一个更好的解决方案。感谢您的帮助。最干净的解决方案是使
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()
如果这些类都是从Objective-C派生的,那么有一个简单的解决方案:您可以使用键值。在我的代码中,
a
的等价物不是从任何东西派生的,但是B
是SKSpriteNode
的一个子类。如果您想使用KVO,这是不行的。如果您想要一个简单的解决方案,那么从NSObject派生一个对象来实现这一点是值得的。令人惊讶地让人想起我说过的话。:)ObjC有自己的优势。这是一个完美的用例,这正是我所说的。
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()
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()