Ios 如何解决swift 4中的“从错误线程访问的域”问题
我试图调试和跟踪错误发生的行,在阅读Ios 如何解决swift 4中的“从错误线程访问的域”问题,ios,swift,realm,background-thread,uisearchbardelegate,Ios,Swift,Realm,Background Thread,Uisearchbardelegate,我试图调试和跟踪错误发生的行,在阅读打印(tcb_filteredArray)后发现错误发生,我试图将打印(tcb_filteredArray)放在self.tableView.reloadData()的下方,并再次调试和跟踪,但仍然在打印中发生错误(tcb_filteredArray) 我的搜索筛选代码 let realm = try! Realm() let tcb = realm.objects(TrialCourtBranches.self)
打印(tcb_filteredArray)
后发现错误发生,我试图将打印(tcb_filteredArray)
放在self.tableView.reloadData()的下方,并再次调试和跟踪,但仍然在打印中发生错误(tcb_filteredArray)
我的搜索筛选代码
let realm = try! Realm()
let tcb = realm.objects(TrialCourtBranches.self)
let tcb_safe = ThreadSafeReference(to: tcb)
DispatchQueue.global(qos: .userInitiated).sync {
guard let filtered = realm.resolve(tcb_safe) else{ return }
tcb_filteredArray = filtered.filter({ $0.branch_name.lowercased().contains(searchText.lowercased()) || ($0.loc?.pc?.province.lowercased().contains(searchText.lowercased()))! || ($0.loc?.pc?.city_municipality.lowercased().contains(searchText.lowercased()))! || $0.office_no.lowercased().contains(searchText.lowercased())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
默认情况下,只能从创建领域对象的线程访问领域对象。因此,在后台线程上创建的筛选对象数组不能直接在主线程上访问
Realm为此提供了两种解决方案-有关更多详细信息,请参阅
这篇文章介绍了几种解决问题的方法:
创建包含相关数据的非托管领域对象(该问题仅在领域支持的对象中出现)
将数据读出到线程安全类型(例如字符串、int等)的变量中
使用新的ThreadSafeReference
类-执行以下步骤:
- 在原始线程中创建引用:
let personRef=ThreadSafeReference(to:person)
(其中,person
是一个领域支持的对象)
- 在第二个线程块内,解析引用:
let realm = try! Realm()
guard let person = realm.resolve(personRef) else {
return // person was deleted
}
如果您选择此路径,则需要将数组中的每个项包装在线程安全引用中。默认情况下,只能从创建域对象的线程访问域对象。因此,在后台线程上创建的筛选对象数组不能直接在主线程上访问
Realm为此提供了两种解决方案-有关更多详细信息,请参阅
这篇文章介绍了几种解决问题的方法:
创建包含相关数据的非托管领域对象(该问题仅在领域支持的对象中出现)
将数据读出到线程安全类型(例如字符串、int等)的变量中
使用新的ThreadSafeReference
类-执行以下步骤:
- 在原始线程中创建引用:
let personRef=ThreadSafeReference(to:person)
(其中,person
是一个领域支持的对象)
- 在第二个线程块内,解析引用:
let realm = try! Realm()
guard let person = realm.resolve(personRef) else {
return // person was deleted
}
如果您选择此路线,则需要将数组中的每个项目包装在ThreadSafeReference
中。这是正确答案
searchBar.rx.text.orEmpty.debounce(0.3, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.filter { !$0.isEmpty }
.observeOn(MainScheduler.instance)
.subscribe(onNext: { (data) in
let realm = try! Realm()
let tcb = realm.objects(TrialCourtBranches.self)
let predicate = NSPredicate(format: "(branch_name CONTAINS[c] %@) OR (office_no CONTAINS[c] %@) OR (loc.pc.city_municipality CONTAINS[c] %@) OR (loc.pc.province CONTAINS[c] %@) OR (loc.address1 CONTAINS[c] %@)",data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased())
tcb_filteredArray = tcb.filter(predicate)
self.tableView.reloadData()
}, onError: { (errorResult) in
print(errorResult)
}, onCompleted: {
print("onCompleted")
}, onDisposed: {
print("onDisposed")
})
.disposed(by: bag)
这是正确答案
searchBar.rx.text.orEmpty.debounce(0.3, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.filter { !$0.isEmpty }
.observeOn(MainScheduler.instance)
.subscribe(onNext: { (data) in
let realm = try! Realm()
let tcb = realm.objects(TrialCourtBranches.self)
let predicate = NSPredicate(format: "(branch_name CONTAINS[c] %@) OR (office_no CONTAINS[c] %@) OR (loc.pc.city_municipality CONTAINS[c] %@) OR (loc.pc.province CONTAINS[c] %@) OR (loc.address1 CONTAINS[c] %@)",data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased(),data.lowercased())
tcb_filteredArray = tcb.filter(predicate)
self.tableView.reloadData()
}, onError: { (errorResult) in
print(errorResult)
}, onCompleted: {
print("onCompleted")
}, onDisposed: {
print("onDisposed")
})
.disposed(by: bag)
我会试试这个@Rich TolleyI先生我编辑了我的代码请看一下顶部,有一个错误@RichTolley@jpcarts23看起来您正在将原始集合传递到ThreadSafeReference
,而不是经过筛选的输出,因此您的类型不匹配。不确定ThreadSafeReference
可以包装哪些类型-您可能需要o使用映射单独包装每个领域对象引用,然后在另一个侧编辑的帖子上再次打开它们,请看一看,仍然不匹配@Rich tolley类似于let tcbSafeArray=tcbFilteredArray.map{ThreadSafeReference(to:$0)}
,然后逐个展开。另外,主线程块防护罩中缺少let
,我将尝试此方法@Rich TolleyI先生编辑了我的代码请查看顶部,有一个错误@RichTolley@jpcarts23看起来您正在将原始集合传递到ThreadSafeReference
,而不是filt您可能需要使用映射单独包装每个领域对象引用,然后在另一篇侧编辑的文章中再次打开它们,请看一看,仍然不匹配@Rich tolley类似于let tcbSafeArray=tcbFilteredArray.map的内容{ThreadSafeReference(to:$0)}
,然后分别将其展开。此外,主线程块guard中缺少let