RxSwift 调用 bind 立即触发 vs subscribe(onNext: )

Posted

技术标签:

【中文标题】RxSwift 调用 bind 立即触发 vs subscribe(onNext: )【英文标题】:RxSwift calling bind fires immediately vs subscribe(onNext: ) 【发布时间】:2019-08-20 21:53:25 【问题描述】:

我读过的所有内容都说bind(to:) 在其中调用subscribe(onNext:)。所以我认为我应该能够交换一些东西,但是当我使用 `bind(to:) 时,它绑定的东西会立即触发。这是我的例子:

ButtonCollectionViewCell

class ButtonCollectionViewCell: UICollectionViewCell 

    lazy var buttonTapped: Observable<Void> =  _buttonTapped.asObservable() ()
    private var _buttonTapped = PublishSubject<Void>()
    private var disposeBag = DisposeBag()

    @IBOutlet private weak var textLabel: UILabel!
    @IBOutlet private weak var actionButton: UIButton!

    // MARK: - Lifecycle

    override func awakeFromNib() 
        super.awakeFromNib()

        actionButton.rx.tap.bind(to: _buttonTapped).disposed(by: disposeBag)
    

    override func prepareForReuse() 
        disposeBag = DisposeBag()
    


现在,当我在下面执行以下操作时,一切都按预期工作,当我点击按钮时它会打印到控制台

带有集合视图的 ViewController

func createButtonCell() 
    let buttonCell = ButtonCollectionViewCell() // there's more code to create it, this is just for simplicity
    buttonCell.buttonTapped.subscribe  _ in
        print("tapped")
    .disposed(by: disposeBag)
    return buttonCell

但是,如果我将以上内容更改为:

func createButtonCell() 
    let buttonCell = ButtonCollectionViewCell()
    buttonCell.buttonTapped.bind(to: buttonTapped)
    return buttonCell


private func buttonTapped(_ sender: Observable<Void>) 
    print("tapped")

"tapped" 是在我滚动到单元格之前打印出来的,我假设是在创建它的时候。

我不明白这一点。我以为我几乎可以换掉实现?我想使用上面的第二个示例,因为我认为它更整洁,但不知道如何。

【问题讨论】:

【参考方案1】:

你的两个例子不一样...

在第一个示例中,您有:.subscribe _ in print("tapped") ,这不是subscribe(onNext:) 调用。正在使用订阅上的 last 闭包,而不是第一个。即,你打电话给subscribe(onDisposed:)

另外,您的ButtonCollectionViewCell 设置错误。您在只调用一次的awakeFromNib() 中绑定,并在多次调用的prepareForReuse() 中释放。两者之一需要移动到更合适的地方...

更新

您可以在重新安装 disposeBag 后重新绑定您的主题,或者您不能首先将链条放入 dispose bag 中,方法是:

_ = actionButton.rx.tap
    .takeUntil(rx.deallocating)
    .bind(to: _buttonTapped)

【讨论】:

啊,谢谢!你会建议我在单元设置中将绑定移动到哪里?

以上是关于RxSwift 调用 bind 立即触发 vs subscribe(onNext: )的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift 简单 withLatestFrom 不触发

ReactiveCocoa vs RxSwift - 优点和缺点?

使用 RxSwift 触发的两个事件

使用 RxSwift 进行分页 API 调用

RxSwift 使 Observable 触发一个主题

一旦网络在 RxSwift 中断开,再次触发 api