如何在通过kvo观察领域列表类型时获得“旧”值

时间:2016-11-04 10:42:03

标签: ios swift realm key-value-observing

我需要观察realm对象的List类型值。

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

问题是a在observeValueForKeyPath函数中无法访问“old”值。

如果我在该功能中记录“更改”,则显示以下内容而不是传统的“旧”& “新建”。

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

这意味着什么以及如何获取“旧”价值?

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

1 个答案:

答案 0 :(得分:1)

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

  

观察Object子类的非托管实例的属性是否有效   就像任何其他动态属性一样,但请注意,你不能   将对象添加到Realm(使用realm.add(obj)或其他类似对象)   方法)虽然它有任何注册的观察员。

上面引用的另一个关键点是观察非托管Realm模型对象与观察“普通”非Realm对象没什么不同。在您的示例中,这正是您所做的,因为您不会将任何对象添加到数据库中。

所以,你是KVO观察一个集合(users),每次有东西被添加到集合时你都会收到通知,但它会是关于更改的集合而不是新的对象的值。集合。

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

在上面的示例中,.indexesKey指的是新添加的对象的索引,.newKey指的是新添加的对象。

如果您更改集合中对象的属性值,则根本不会收到通知!

要获得此类通知,您必须观察集合中的每个对象。