我在这段代码上遇到了一些崩溃:
SRNetwork.provider
.request(SRService.postData(user_id: userId))
.mapArray(STrain.self)
.observeOn(ConcurrentDispatchQueueScheduler.init(queue: SDispatchQueue.dataTrain.getQueue()))
.subscribe({ (event) -> Void in
switch event {
case .next(let response):
self.train.value = response
SRealmTrain.sharedInstance.cacheTrain(response)
case .error(let error):
SRealmTrain.sharedInstance.fetchTrainRx(userId) //CRASH IS HERE
.bindTo(self.train)
.addDisposableTo(self.disposeBag)
print("\(error)")
default: break;
}
})
.addDisposableTo(disposeBag);
我认为问题是我不在MainScheduler.instance
和main thread
上的public func fetchTrainRx(_ userId: String) -> Observable<[STrain]> {
let predicate = NSPredicate(format: "userId == %@", userId)
if let realm = realm {
return Observable.from(realm
.objects(SRTrain.self)
.filter(predicate)
.sorted(byProperty: "order", ascending: true))
.map ({
$0.map(STrain.init)
})
}
return Observable.just([]);
}
和rxRealm观看,但我不想要它。有可能解决它吗?
fetchTrainRx :
public boolean bobThere(String str) {
for (int i = 0 ; i < str.length()-2 ; i++){
if( str.substring(i , i+1).equals("b") && str.substring(i+2 , i+3).equals("b"))
return true;}
return false;
}
答案 0 :(得分:3)
Realm的通知默认在主线程(安装了应用程序的默认runloop)上提供。这就是为什么在你的代码中你得到一个例外&#34;只能在runloops中添加通知块&#34;因为您尝试在没有runloop的后台线程中订阅通知。
当您使用Observable.from( ... some realm collection ... )
时,RxRealm会订阅Realm自身发送的通知以及您获得异常时的通知,因为您的代码明确切换到此行.observeOn(ConcurrentDispatchQueueScheduler.init(queue...
上的后台线程。
您可以通过两种不同的方式来解决当前问题:
1)不要在subscribe
运算符之前切换到后台队列(假设您正在主线程上执行Rx订阅)
2)在fetchTrainRx
方法中使用DispatchQueue.main.sync
在主线程上创建Observable。
这可以解决您当前的问题。
在任何情况下 - 从你的代码我看到你在你的类中的某个地方存储了Realm引用(或者至少它看起来像你这样做),这不是最佳实践。如果您正在处理不同的线程,请每次使用let realm = try! Realm()
在当前线程上获取Realm引用;这将确保您始终使用正确的领域实例。