RxSwift 调用绑定会立即触发 vs subscribe(onNext:)
RxSwift calling bind fires immediately vs subscribe(onNext: )
我读过的所有内容都说 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 具有 collection 视图
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"
是在我滚动到单元格之前打印出来的,我假设是在创建它的时候。
我不明白这个。我以为我几乎可以换掉这些实现?我想在那里使用上面的第二个示例,因为我认为它更简洁,但不知道如何使用。
你的两个例子不一样...
在第一个示例中,您有:.subscribe { _ in print("tapped") }
而不是 subscribe(onNext:)
调用。正在使用订阅上的 last 闭包,而不是第一个。即,您正在呼叫 subscribe(onDisposed:)
.
此外,您的 ButtonCollectionViewCell
设置有误。您绑定只调用一次的 awakeFromNib()
,并在多次调用的 prepareForReuse()
中进行处理。两者之一需要移动到更合适的地方...
更新
您可以在重新安装 disposeBag 后重新绑定您的主题,或者您可以通过以下方式首先不将链条放入处理袋中:
_ = actionButton.rx.tap
.takeUntil(rx.deallocating)
.bind(to: _buttonTapped)
我读过的所有内容都说 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 具有 collection 视图
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"
是在我滚动到单元格之前打印出来的,我假设是在创建它的时候。
我不明白这个。我以为我几乎可以换掉这些实现?我想在那里使用上面的第二个示例,因为我认为它更简洁,但不知道如何使用。
你的两个例子不一样...
在第一个示例中,您有:.subscribe { _ in print("tapped") }
而不是 subscribe(onNext:)
调用。正在使用订阅上的 last 闭包,而不是第一个。即,您正在呼叫 subscribe(onDisposed:)
.
此外,您的 ButtonCollectionViewCell
设置有误。您绑定只调用一次的 awakeFromNib()
,并在多次调用的 prepareForReuse()
中进行处理。两者之一需要移动到更合适的地方...
更新
您可以在重新安装 disposeBag 后重新绑定您的主题,或者您可以通过以下方式首先不将链条放入处理袋中:
_ = actionButton.rx.tap
.takeUntil(rx.deallocating)
.bind(to: _buttonTapped)