通过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。
我需要观察领域对象的列表类型值。
我需要在调用观察者时访问新值和旧值。
问题是无法访问 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.
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。