Realm Swift文档指出,您可以使用KVO观察模型类上使用的大多数属性 . 使用ReactiveCocoa,对于我在模型类上的每个属性,我创建了一个类似的 rac_
前缀属性,它发送值更改,然后我可以使用它来绑定到MVVM样式体系结构中的视图 .
示例模型类可能如下所示:
class Post: Object {
dynamic var text = ""
private(set) lazy var rac_text: AnyProperty<String> = { [unowned self] in
return AnyProperty(initialValue: self.name, signal: self.rac_valuesForKeyPath("text", observer: self).toSignal().takeUntil(self.willDeallocSignal())
}()
}
这是非常方便的因为1)它从外部不可变( AnyProperty
vs MutableProperty
和2)只有模型与 .takeUntil(self.willDeallocSignal())
一起生存 . (我也想问一下,这里需要_1317161位吗?我不确定 self
是否被捕获,总是那么糟糕) .
问题出在 List
属性中 . 列表可以在objective-c中表示 . 关键 Value 观察工作得很好,有一个主要的警告 .
使用关系列表属性获取相同的类:
class Post: Object {
let users: List<User> = List<User>()
}
相应的反应性观察属性应该看起来像是:
private(set) lazy var rac_users: AnyProperty<List<User>> = {
return AnyProperty(initialValue: self.users, signal: self.rac_valuesForKeyPath("users", observer: self).toSignal().takeUntil(self.willDeallocSignal()))
}()
但是在观察时,信号不会发出 List
个对象,它会发出 RLMArray
个对象 . 我不得不jerryrig一个看起来像这样的信号发生器:
private(set) lazy var rac_posts: AnyProperty<List<Post>> = { [unowned self] in
return AnyProperty<List<Post>>(initialValue: self.posts, producer: self.rac_valuesForKeyPath("posts", observer: self)
.toSignalProducer()
.assumeNoErrors()
.map { $0 as! RLMArray }
.map { array in
var list = List<Post>()
for i in 0..<array.count {
if let element = array[i] as? Post {
list.append(element)
}
}
return list
})
}()
当然, if let
语句总是失败,因为 RLMObject
无法强制转换为 Post
. 所以我要么a)一种方法将 RLMObject
转换为 Object
s或b)一种在列表属性上发出kvo的方法 . 我使用传统的KVO进行了测试并获得了相同的结果 .
2 回答
您可以使用addNotificationBlock通过Realm Swift观察
List
类型的属性 .此方法采用闭包,在 every 更改时调用 . 至少只要您不阻止运行循环,通知就可能会合并 . 通过此机制也会报告初始值,因此您可能会获得其他信号,这可能是您不期望的 .
您应该可以使用Reactive Cocoa连接它,如下所示:
合并#3359后,您还将获得细粒度通知,这将通知您列表中的详细更改 .