Realm Swift 文档指出,您在模型类上使用的大多数属性都可以使用 KVO 来观察。使用 ReactiveCocoa,对于模型类上的每个属性,我创建一个类似的 rac_
前缀属性,该属性发送值更改,然后我可以使用它绑定(bind)到 MVVM 风格架构中的 View 。
示例模型类可能如下所示:
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
与 MutableProperty
和 2)只要模型与 一起存在,它就存在。 takeUntil(self.willDeallocSignal())
。 (我还想问,这里有必要使用[unowned self]
位吗?我不确定self
是否被捕获,总是不擅长)。
问题出在 List
属性上。列表不能被标记为动态,这是有道理的,它们的类型不能在 Objective-C 中表示。键值观察效果很好,但有一个主要警告。
采用具有关系列表属性的同一类:
class Post: Object {
let users: List<User> = List<User>()
}
相应的 react 性观察属性应该类似于:
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
对象。我不得不临时搭建一个信号生成器,如下所示:
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 的方法,要么 b) 一种在发出列表的列表属性上进行 kvo 的方法。我使用传统的 KVO 进行了测试,得到了相同的结果。
最佳答案
您可以使用 Realm Swift 观察 List
类型的属性 addNotificationBlock
.
此方法采用一个闭包,每次更改时都会调用该闭包。至少只要您不阻塞运行循环,通知就可能会合并。初始值也是通过此机制报告的,因此您可能会通过该机制获得您可能意想不到的其他信号。
您应该能够将其与 Reactive Cocoa 连接起来,如下所示:
private(set) lazy var rac_posts: AnyProperty<List<Post>> = { [unowned self] in
return AnyProperty<List<Post>>(initialValue: self.posts, signal: Signal<List<Post>>() { [unowned self] observer in
let notificationToken = self.posts.addNotificationBlock { list in
observer.sendNext(list)
}
return ActionDisposable() {
notificationToken.stop()
}
}
}()
一次#3359合并后,您还将收到细粒度的通知,通知您列表中的详细更改。
关于ios - Realm 列表 KVO 观察,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36638546/