gpt4 book ai didi

ios - RxSwift PublishSubject 被无意中处置

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:36:26 26 4
gpt4 key购买 nike

我有一个 View Controller ,它打开一个模态视图 Controller 供用户从其库中选择图像。为此,我使用了我编写的 DKImagePickerController 的 Rx 包装器。

View Controller中的相关代码如下:

fileprivate func addPicturesFromLibrary() {
guard let viewModel = self.viewModel else { return }

let pickerController = DKImagePickerController()
pickerController.singleSelect = false
pickerController.maxSelectableCount = 10
pickerController.showsCancelButton = true
pickerController.sourceType = .photo

pickerController.rx.didSelectAssets()
.debug("👍 1")
.bind(to: viewModel.addAssetsInput)
.disposed(by: disposeBag)

self.present(pickerController, animated: true, completion: nil)
}

我的 View 模型如下所示:

class MediaViewModel {

var selectedImages = Variable<[MediaListingImage]>([])

public let addAssetsInput = PublishSubject<DKAsset>()

init() {
bind()
}

private func bind() {
addAssetsInput
.debug("👍 2")
.flatMap {
$0.rx.fetchOriginalImage()
}
.map {
MediaListingImage.local($0)
}
.subscribe(onNext: { [weak self] (mediaListingImage) in
self?.selectedImages.value.append(mediaListingImage)
})
.disposed(by: disposeBag)
}
}

当我打开第一个模式选择器时,它按预期工作。但是,当它释放时, View 模型中的绑定(bind) 也会释放,因此模态视图 Controller 的后续呈现将不起作用。

这是我在控制台中获得的日志,这可能有助于您理解我看到的内容:

2017-11-15 17:33:15.490: 👍 2 -> subscribed
2017-11-15 17:33:21.452: 👍 1 -> subscribed
2017-11-15 17:33:23.902: 👍 1 -> Event next(<DKImagePickerController.DKAsset: 0x6080002ab940>)
2017-11-15 17:33:23.902: 👍 2 -> Event next(<DKImagePickerController.DKAsset: 0x6080002ab940>)
2017-11-15 17:33:23.902: 👍 1 -> Event completed
2017-11-15 17:33:23.903: 👍 2 -> Event completed
2017-11-15 17:33:23.903: 👍 2 -> isDisposed
2017-11-15 17:33:23.903: 👍 1 -> isDisposed
2017-11-15 17:33:29.924: 👍 1 -> subscribed
2017-11-15 17:33:33.114: 👍 1 -> Event next(<DKImagePickerController.DKAsset: 0x60c0002a62a0>)
2017-11-15 17:33:33.114: 👍 1 -> Event completed
2017-11-15 17:33:33.114: 👍 1 -> isDisposed

如果我将 View Controller 中的代码更改为:

    pickerController.rx.didSelectAssets()
.debug("👍 1")
.subscribe(onNext: { (asset) in
viewModel.addAssetsInput.onNext(asset)
})
.disposed(by: disposeBag)

它按预期工作。但是,我发现在这种情况下使用 bind 更优雅,如果可能的话我想继续使用它。

是什么触发了 View 模型中 PublishSubject 的绑定(bind)以进行处理?如何在不泄漏资源的情况下防止它?

最佳答案

我怀疑因为 completed 通过第二条链(MediaViewModel.bind 中的链)传播,它将不再接收任何事件。我想你会想在这里使用 subscribe(onNext: { ... }) 而不是 bind 这样你就可以避免发送错误和完成事件。

另一种选择是使用 PublishRelay 而不是 PublishSubject

PublishRelay is a wrapper for PublishSubject. Unlike PublishSubject it can't terminate with error or completed.

关于ios - RxSwift PublishSubject 被无意中处置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47316858/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com