RxSwift调用绑定立即触发vs订阅(onNext:)

时间:2019-08-20 21:53:25

标签: ios swift rx-swift

我读过的所有内容都表明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 个答案:

答案 0 :(得分:1)

您的两个示例不相同...

在第一个示例中,您有:.subscribe { _ in print("tapped") },这不是subscribe(onNext:)的调用。正在使用预订上的 last 闭包,而不是第一个。即,您正在呼叫subscribe(onDisposed:)

此外,您的ButtonCollectionViewCell设置有误。您绑定仅被调用一次的awakeFromNib(),并放置在被多次调用的prepareForReuse()中。需要将两者之一移到更合适的地方...

更新

您可以在重新放置disposeBag之后重新绑定主题,或者首先不能通过以下操作将链条放在处置袋中:

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