2016-11-04 57 views
0

我需要观察领域对象的List类型值。如何在观察领域时获得“旧”值清单类型由kvo

当观察者被调用时,我需要访问新的和旧的值。

问题是a不能访问observeValueForKeyPath函数中的“旧”值。

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

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

我没有看到代码中实际将对象添加到Realm的地方。你只是观察一个Object的一个集合属性,所以你回到'change'参数集合的变化,而不是单个元素。 –

+0

我需要观察一个领域对象模型,不管它是否保存到领域。 – Bigair

回答

1

首先,我会建议有关领域志愿here的文档的一个很好看的。您会注意到,将观察者添加到非托管对象(尚未添加到Realm中),然后将该对象添加到数据库是不可能的,因此您需要基于此设计观察策略:

观察对象子类的非托管实例的属性与其他动态属性一样工作 ,但请注意,您不能将对象添加到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指新添加的对象。

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

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