我有以下Realm对象:
class GeolocationObject: Object {
dynamic var id: String = UUID().uuidString
dynamic var latitude: Double = 0
dynamic var longitude: Double = 0
let addresses = LinkingObjects.init(fromType: AddressObject.self, property: "geolocation")
override static func primaryKey() -> String? {
return "id"
}
}
我也有链接地址对象(为简单起见,我只有一个道路属性):
class AddressObject: Object {
dynamic public var id: String = UUID().uuidString
dynamic var road: String = ""
dynamic var geolocation: GeolocationObject?
override static func primaryKey() -> String? {
return "id"
}
}
正如您所看到的,我与GeolocationObject
建立了To-One关系,并且对于我的应用程序的需求,有可能在同一个Geolocation上,我可能有很多AddressObjects
。因此,LinkingObjects
中有GeolocationObject
个属性。
我创建了一个带有RxSwift和RxRealm的反应式抽象层(RealmProvider
只提供了一种更简单的Realm写入事务的方法):
class GeolocationViewModel {
let disposeBag: DisposeBag
let geolocationObject: GeolocationObject
let id: String
var latitude: Variable<Double>
var longitude: Variable<Double>
let addresses: Observable<[AddressViewModel]>
init(geolocationObject: GeolocationObject) {
self.disposeBag = DisposeBag()
self.geolocationObject = geolocationObject
self.id = self.geolocationObject.id
self.latitude = Variable(self.geolocationObject.latitude)
self.longitude = Variable(self.geolocationObject.longitude)
self.addresses =
Observable.array(from: self.geolocationObject.addresses)
.map({ $0.flatMap({ AddressViewModel.init(addressObject: $0) }) })
self.latitude.asObservable()
.subscribe(onNext: { [unowned self] (latitude) in
RealmProvider.commitWrite {
self.geolocationObject.latitude = latitude
}
})
.disposed(by: disposeBag)
self.longitude.asObservable()
.subscribe(onNext: { [unowned self] (longitude) in
RealmProvider.commitWrite {
self.geolocationObject.longitude = longitude
}
})
.disposed(by: disposeBag)
}
}
和
class AddressViewModel {
let disposeBag: DisposeBag
let addressObject: AddressObject
let id: String
var road: Variable<String>
var geolocation: Variable<GeolocationViewModel?>
init(addressObject: AddressObject) {
self.disposeBag = DisposeBag()
self.addressObject = addressObject
self.id = self.addressObject.id
self.road = Variable(self.addressObject.road)
if let geolocationObject = self.addressObject.geolocation {
self.geolocation = Variable(GeolocationViewModel.init(geolocationObject: geolocationObject))
} else {
self.geolocation = Variable(nil)
}
self.road.asObservable()
.debug()
.subscribe(onNext: { [unowned self] (road) in
RealmProvider.commitWrite {
self.addressObject.road = road
}
})
.disposed(by: disposeBag)
self.geolocation.asObservable()
.subscribe(onNext: { [unowned self] (geolocationViewModel) in
RealmProvider.commitWrite {
self.addressObject.geolocation = geolocationViewModel?.geolocationObject
}
})
.disposed(by: disposeBag)
}
正如您所看到的,我已将LinkingObjects
属性作为Observable
传递,因此如果出现更改,系统会通知您。
简而言之,我创建了一个带有地理位置对象的地址。
一切都很好,直到现在。我抓住AddressViewType
,然后改变道路(Variable
)。如果我通过AddressViewType
订阅GeolocationViewType
数组,则会正确通知,但会一直触发。
例如:
let geolocationViewModel = GeolocationViewModel(geolocationObject: GeolocationViewModel)
let addressViewModel = AddressViewModel(addressObject: AddressObject())
addressViewModel.road.value = test1
addressViewModel.geolocation.value = geolocationViewModel
geolocationViewModel.addresses.subscribe(onNext: { addressArray in
print(addressArray[0].road)
})
.disposed(by: disposeBag)
如果我尝试像这样改变addressViewModel的道路:
addressViewModel.road.value = "Test2"
它正确通知print语句并打印。但它随着新价值一直在发射!它不会仅发送一次打印。
我发现如果Observable
上地址的GeolocationObject
是这样的话,它会停止:
self.addresses =
Observable.array(from: self.geolocationObject.addresses)
.map({ $0.flatMap({ AddressViewModel.init(addressObject: $0) }) })
.replay(1)
后来我又添加了.share()
如果我不放.replay(1)
,为什么它会一直开火?
它不应该只发送一次并停止吗?