物业观察员对物业财产的迅速

时间:2016-07-13 03:15:05

标签: swift

标题有点令人困惑,但它几乎说明了一切。我想在属性的属性上有一个属性观察者:

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

}

这似乎是一个非常混乱的解决方案,似乎应该有一个更好的解决方案。谢谢你的帮助。

1 个答案:

答案 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()
相关问题