Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.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 如何从BehaviorRelay observable更新tableView?_Ios_Swift_Rx Swift - Fatal编程技术网

Ios 如何从BehaviorRelay observable更新tableView?

Ios 如何从BehaviorRelay observable更新tableView?,ios,swift,rx-swift,Ios,Swift,Rx Swift,我正试图用油门在表视图中进行搜索 这里有ViewModel中的BehaviorRelay var countryCodes: BehaviorRelay<[CountryDialElement]> = BehaviorRelay<[CountryDialElement]>(value:[]) 在这里,我将Rx绑定到ViewController中的UISearchBar searchBar .rx .text .orEmpty

我正试图用油门在表视图中进行搜索

这里有ViewModel中的BehaviorRelay

var countryCodes: BehaviorRelay<[CountryDialElement]> = BehaviorRelay<[CountryDialElement]>(value:[])
在这里,我将Rx绑定到ViewController中的UISearchBar

searchBar
      .rx
      .text
      .orEmpty
      .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
      .distinctUntilChanged()
      .subscribe { [weak self] query in
        guard
          let query = query.element else { return }
        self?.viewModel.params.searchText.accept(query)
      }
      .disposed(by: disposeBag)
然后在ViewModel中,我尝试过滤数据并将过滤后的数据推送到dataSource,以更新tableView

Observable.combineLatest(params.countryCodes, params.searchText) { items, query in
      return items.filter({ item in
        item.name.lowercased().contains(query.lowercased()) || item.dialCode.lowercased().contains(query.lowercased())
      })
    }.subscribe(onNext: { resultArray in
      self.params.countryCodes.accept(resultArray)
    })
    .disposed(by: disposeBag)
但我得到了这种类型的错误

Reentrancy anomaly was detected.
This behavior breaks the grammar because there is overlapping between sequence events.
The observable sequence is trying to send an event before sending the previous event has finished.
Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in an expected way.
我正在努力实现:

  • 具有可观察数组的绑定表视图
  • 在搜索栏中键入文本
  • 可观测滤波器
  • 更新可观察,重新加载tableView

  • 我注意到的第一件事。。。您有两个行为关系定义为
    var
    。您应该始终使用
    let
    来定义它们

    你没有发布足够的代码来演示错误,但是在错误消息中向你解释的根本问题是,你打破了可观察语法,因为在推送数据的过程中,你通过一个可观察的数据来推动数据。如果允许,它将形成一个无限递归调用,从而使堆栈溢出

    在当前事件完成发送之前,不要发送事件。如果你不使用这么多的继电器,那会有很大帮助

    你没有说任何关于数组中的项目来自何处的信息,这也让你很难帮助

    考虑一下这样的情况:

    Observable.combineLatest(
        searchBar.rx.text.orEmpty
            .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .startWith(""),
        sourceOfItems(),
        resultSelector: { searchTerm, items in
            items.filter { $0.code.contains(searchTerm) }
        }
    )
    .bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
        let countryCell = cell as! CountryDialTableViewCell
        countryCell.configure(model)
    }
    .disposed(by: disposeBag)
    

    谢谢你,丹尼尔。这对我帮助很大。谢谢你的建议,我的代码从你的代码片段的灵感中经过一点重构后现在可以工作了。实际上,数据来自本地JSON文件。
    Reentrancy anomaly was detected.
    This behavior breaks the grammar because there is overlapping between sequence events.
    The observable sequence is trying to send an event before sending the previous event has finished.
    Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in an expected way.
    
    Observable.combineLatest(
        searchBar.rx.text.orEmpty
            .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .startWith(""),
        sourceOfItems(),
        resultSelector: { searchTerm, items in
            items.filter { $0.code.contains(searchTerm) }
        }
    )
    .bind(to: tableView.rx.items(cellIdentifier: "CountryDialTableViewCell")) { index, model, cell in
        let countryCell = cell as! CountryDialTableViewCell
        countryCell.configure(model)
    }
    .disposed(by: disposeBag)