NSPredicate更改时不会触发域通知

时间:2016-11-22 21:48:50

标签: swift realm nspredicate

我在Realm中有一个简单的勾选列表,我使用NotificationToken检查数据源中的更新,然后使用以下项更新tableView:

class Item : Object {
    dynamic var name = ""
    dynamic var isTickedOff = false
    dynamic var timeStamp : Date?
}

模特:

var items: Results<Item> {
    get {
        let results = self.realm.objects(Item.self)
        let alphabetic = SortDescriptor(property: "name", ascending: true)
        let tickedOff = SortDescriptor(property: "isTickedOff", ascending: true)
        let timestamp = SortDescriptor(property: "timeStamp", ascending: false)
        return results.sorted(by: [tickedOff, timestamp, alphabetic]).filter("isTickedOff = %@ || isTickedOff = %@", false, self.includeAll)
    }
}

我的tableview中有一个开关,用户可以在其中更改self.includeAll属性。

插入,删除项目或选择它们(导致将它们设置为isTickedOff或!isTickedOff)时会触发通知并更新tableView。但是,即使修改了self.includeAll属性,更改items属性也不会触发通知。当用户触发切换时,我可以包含self.tableView.reloadData(),但我希望通过通知获得更流畅的动画。

是我,谁理解通知错误或是错误?

提前致谢!

1 个答案:

答案 0 :(得分:2)

Realm不会观察外部属性,因此无法知道谓词查询中正在使用的属性何时发生更改,然后随后生成更改通知。

下次访问items时,会给它一个足够的事件来重新计算内容,但到那时,它不会触发通知。

显然,就像你说的那样,最简单的解决方案是简单地调用tableView.reloadData(),因为这会强制重新items,但不会有动画。或者相反,like this SO question says,您可以调用tableView.reloadSections来实际启用“重新洗牌”动画。

最后,它可能是一个相当脏的黑客,但如果您仍然希望它触发基于Realm的更改通知,您可能只需打开Realm写入通知,更改includeAll属性,然后关闭写入事务试图“欺骗”Realm执行更新。

最后一点需要注意。我可能没有足够的信息,所以这可能是不正确的,但是如果您在items属性上注册Realm通知块,请注意您实现该getter的方式意味着新对象每次调用时都会生成。将该属性标记为lazy可能更合适,因此在第一次调用后将其保存。