Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何解决swift 4中的“从错误线程访问的域”问题_Ios_Swift_Realm_Background Thread_Uisearchbardelegate - Fatal编程技术网

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