我在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()
,但我希望通过通知获得更流畅的动画。
是我,谁理解通知错误或是错误?
提前致谢!
答案 0 :(得分:2)
Realm不会观察外部属性,因此无法知道谓词查询中正在使用的属性何时发生更改,然后随后生成更改通知。
下次访问items
时,会给它一个足够的事件来重新计算内容,但到那时,它不会触发通知。
显然,就像你说的那样,最简单的解决方案是简单地调用tableView.reloadData()
,因为这会强制重新items
,但不会有动画。或者相反,like this SO question says,您可以调用tableView.reloadSections
来实际启用“重新洗牌”动画。
最后,它可能是一个相当脏的黑客,但如果您仍然希望它触发基于Realm的更改通知,您可能只需打开Realm写入通知,更改includeAll
属性,然后关闭写入事务试图“欺骗”Realm执行更新。
最后一点需要注意。我可能没有足够的信息,所以这可能是不正确的,但是如果您在items
属性上注册Realm通知块,请注意您实现该getter的方式意味着新对象每次调用时都会生成。将该属性标记为lazy
可能更合适,因此在第一次调用后将其保存。