简体   繁体   中英

RxSwift. Subscription occurs twice

I do not know RxSwift well enough, and could not figure out my problem on my own. I would be very grateful for the help. Sorry for my English.

//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)
    }

I can't understand why the subscription occurs 2 times. That is, I go to service.uploadPhoto (image: image) twice.

I can only speculate here based on the code you posted but you probably don't unsubscribe when the cell gets reused. Therefore and since the disposeBag is held by the ViewController when cellForRowAtIndexPath gets called you will just add another subscription. The subscriptions only get cleared after the ViewController gets deallocated, which is when the DisposeBag gets destroyed.

Here's what I would do for now: The cell should hold the Observable and the DisposeBag instead. You'll have to clear it in 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()
   }
}

and then in your 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
}

At this point you might also want to think about your architecture. For example your could manage the observable supplying the data for the cells so that you can just bind it to the tableview and let rx manage everything. Or you could override TableViewDataSource in a way that your cells can handle their own ViewModels entirely themselves.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM