通过kvo观察领域列表类型时如何获得"old"值

How to get "old" value when observing realm List type by kvo

我需要观察领域对象的列表类型值。

我需要在调用观察者时访问新值和旧值。

问题是无法访问 observeValueForKeyPath 函数中的 "old" 值。

如果我在该函数中记录 "change",它会显示以下内容而不是常规的 "Old" & "New"。

Optional(["new": <__NSArrayI 0x7fcc8bc57150>(
User {
}
)
, "indexes": <_NSCachedIndexSet: 0x7fcc8bc07970>[number of indexes: 1 (in 1 ranges), indexes: (1)], "kind": 2])

这些是什么意思,我如何访问 "old" 值?

import UIKit
import RealmSwift

class ValueContainer: Object {
    let users = List<User>()
}

class User: Object {

}

class ViewController: UIViewController {

    let container = ValueContainer()

    override func viewDidLoad() {
        super.viewDidLoad()

        container.users.appendContentsOf([User(), User(), User(), User()])

        container.addObserver(self, forKeyPath: "users", options: [.New, .Old], context: nil)

    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

        print("---- Observer called ---")
        print("KeyPath:\(keyPath)")

        guard let container = object as? ValueContainer else {
            print("Object cast failed")
            return
        }

        print("Change")
        print(change)

    }


    @IBAction func buttonTap(sender: AnyObject) {
        container.users.insert(User(), atIndex: 1)
    }
}

首先,我建议您仔细阅读有关 Realm KVO 的文档 here。您会注意到,将观察者添加到非托管 object(尚未添加到 Realm)然后将 object 添加到数据库是不可能的,因此您需要设计基于以下内容的观察策略那:

Observing properties of unmanaged instances of Object subclasses works just like with any other dynamic property, but note that you cannot add an object to a Realm (with realm.add(obj) or other similar methods) while it has any registered observers.

从上面的引述中得出的另一个关键结论是,观察一个非托管的 Realm 模型 object 与观察一个 "normal" non-Realm object 没有什么不同。在您的示例中,这正是您所做的,因为您没有将任何 object 添加到数据库中。

因此,您正在 KVO 观察 collection (users),并且每次向 collection 添加内容时您都会收到通知,但这将是关于更改的 collection 而不是 collection.

中 object 的新值
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    print(change?[.indexesKey])
    print(change?[.newKey])
}

上面的例子中.indexesKey指的是新增的索引object,.newKey指的是新增的object.

如果您更改 collection 中 object 的 属性 的值,您根本不会收到通知!

要获得此类通知,您必须观察 collection 中的每个 object。