簡體   English   中英

RxSwift。 訂閱發生兩次

[英]RxSwift. Subscription occurs twice

我不太了解 RxSwift,也無法自己解決我的問題。 我將非常感謝您的幫助。 對不起我的英語不好。

//declare variables    

var loadedImage = BehaviorRelay<UIImage?>(value: nil)

//Subscribe when creating a cell

loadedImage
            .do(onNext: { (_) in
                cell.activityIndicator.startAnimating()
                cell.activityIndicator.isHidden = false
            })
            .flatMap { (image) -> Observable<String> in
                guard let image = image else { return Observable.just("") }
                return service.uploadPhoto(image: image)
            }
            .observeOn(MainScheduler.instance)
            .subscribeNext { (imageName) in
                vc.createEventData.imageName = imageName

                cell.activityIndicator.stopAnimating()
                cell.activityIndicator.isHidden = true

                let currentPhoto = self.object?.placeholderPhoto
                let image = self.loadedImage.value

                cell.photoEventImageView.image = image == nil ? currentPhoto : image

                if let photoPath = self.object?.photoPath, image == nil {
                    if photoPath != "uploads/photos/.png" {
                        let url = URL(string: "http://test-around.profsoft.online/" + photoPath)
                        cell.photoEventImageView.kf.setImage(with: url)

                        if let r = photoPath.range(of: "/", options: .backwards) {
                            let imageName = photoPath.substring(from: r.upperBound)
                            vc.createEventData.imageName = imageName
                        }
                    }
                }

            }
            .disposed(by: disposeBag)

//I throw a signal when choosing a photo

   func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        guard let image = info[.originalImage] as? UIImage else { return }
        loadedImage.accept(image)
        self.viewController?.dismiss(animated: true, completion: nil)
    }

我不明白為什么訂閱會發生 2 次。 也就是我go到service.uploadPhoto(image:image)兩次。

我只能根據您發布的代碼在這里推測,但當單元格被重用時您可能不會取消訂閱。 因此,由於 disposeBag 在調用cellForRowAtIndexPath時由 ViewController 持有,因此您只需添加另一個訂閱。 只有在 ViewController 被釋放后,訂閱才會被清除,也就是 DisposeBag 被銷毀的時候。

這是我現在要做的:單元格應該包含 Observable 和 DisposeBag 。 您必須在prepareForReuse中清除它:

class YourCell: UITableViewCell {
   var disposeBag = DisposeBag()
   var yourObservable: Observable<UIImage?>?

   func configure(with yourObservable: Observable<UIImage?>) {
      yourObservable = yourObservable
         .subscribe(onNext: /*your code*/ }
         .disposed(by: disposeBag)
   }

   override func prepareForReuse() {
      super.prepareForReuse()
      disposeBag = DisposeBag()
   }
}

然后在你的 ViewController 中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let observable = loadedImage /* additional config if needed */
   let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR IDENTIFIER HERE", for: indexPath) as! YourCell
   cell.configure(with: observable)
   return cell
}

此時,您可能還想考慮您的架構。 例如,您可以管理為單元格提供數據的可觀察對象,以便您可以將其綁定到 tableview 並讓 rx 管理所有內容。 或者,您可以覆蓋 TableViewDataSource,使您的單元格可以完全自己處理自己的 ViewModel。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM