RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据

Posted

技术标签:

【中文标题】RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据【英文标题】:RxCocoa-observable is emitting new data from API but tableview.rx.items doesn't show new data 【发布时间】:2018-10-17 10:00:05 【问题描述】:

我是 RxSwift 和 RxCocoa 的新手。

我在本地有一个可用的 REST 服务,它为给定的“id”返回一个电影对象。

在我的故事板上有一个 tableView (UITableView),它有自定义单元格 (MovieCell)。每个电影单元格都有一个名为“nameTextLabel”的 UILabel。我还有一个 textField 可以从用户那里获取请求的 movie.id。

我正在尝试在 tableView 的每一行上显示 movie.title。

import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController 

@IBOutlet var textField: UITextField!
@IBOutlet var tableView: UITableView!
let bag = DisposeBag()

override func viewDidLoad() 
    super.viewDidLoad()
    configureReactiveBinding()

private func configureReactiveBinding() 
    textField.rx.text.asObservable()
        .map  ($0 == "" ? "15" : $0!).lowercased() 
        .map  GetMovieByIdRequest(id: $0) 
        .flatMap  request -> Observable<Movie> in
            return ServiceManager.instance.send(apiRequest: request)
        
    .debug("movie")
// output:
//2018-10-17 16:13:49.320: movie -> subscribed
//2018-10-17 16:13:49.401: movie -> Event next(MovieAdvisor.Movie)
//2018-10-17 16:13:52.021: movie -> Event next(MovieAdvisor.Movie)
    .toArray()
    .debug("tableView")
// output:
//2018-10-17 16:13:49.318: tableView -> subscribed

        .bind(to: tableView.rx.items(cellIdentifier: "movie_cell", cellType:MovieCell.self))  index, model, cell in
            cell.nameTextLabel.text = model.title
        
        .disposed(by: bag)



每次更改 textLabel 时都会打印新的 movie.id,但 tableView 不显示任何数据——即使是初始值也不显示(当 textField 为 "" 时)。

知道如何解决这个问题吗?

添加 debug() 行后,我发现 tableView 只订阅了一次,并且没有下一个事件触发 tableView。我该怎么办? 代码上传到 GitHub github

【问题讨论】:

????我需要一些信息来帮助您...在您的.toArray() 和您的.bind(to:) 之间添加一个.debug("tableView")。将该调试语句的输出添加到您的问题中。 感谢您的快速回复!添加了调试命令,希望对您解决问题有所帮助。 【参考方案1】:

问题在于您的toArray() 运算符。该操作符一直等到序列完成,然后将整个序列作为单个数组发出。在您退出视图控制器之前,您的序列不会完成。

将其替换为 .map [$0] 即可显示电影。您应该问问自己,为什么您的端点只返回一部电影而不是一组电影。

【讨论】:

当我用 .map [$0] 替换 toArray() 时,我得到“无法推断通用参数自身”编译时错误。我的端点只返回 1 部电影的原因是,因为它是 getMovieById,所以它只返回具有给定 id 的电影。你为什么这么建议?使用 Observables 时使用数组会更好吗? 奇怪,我下载了你的 GitHub 项目并进行了替换,它运行良好。一个 tableview 显示一个数组,这就是为什么我很惊讶提供 tableview 的流只发出一个值。【参考方案2】:

尝试替换

`a.subscribe(onNext: movie in
    print(movie.title)
)
.disposed(by: bag)

.observeOn(MainScheduler.instance) 看看它是否有效。

也许将.toArray() 直接移动到ServiceManager.instance.send(apiRequest: request) 之后。

您还可以在每个 RxSwift 运算符之后添加 *.debug("my custom message")* 以查看它是否正在执行。

顺便说一句,我建议为此使用 RxDataSources 框架,而不是裸露的 RxCocoa。

【讨论】:

感谢 debug() 建议。观察主调度器并没有帮助:( 也许将 '.toArray()' 直接移动到 'ServiceManager.instance.send(apiRequest: request)' 之后 我做到了,谢谢!其背后的原因是 .toArray() 等待整个事情完成(这永远不会发生),但您需要它在每次服务请求后发出。

以上是关于RxCocoa-observable 正在从 API 发出新数据,但 tableview.rx.items 不显示新数据的主要内容,如果未能解决你的问题,请参考以下文章

求助,华为AP 2030DN-S 怎么从fit转换为fat

oracle怎样从ap发票查会计分录

Cisco AP-如何识别思科胖瘦AP

华为AP3010DN-AGN升级为胖AP

scp文件传输

锐捷 ac ap 连接 记录