Мой пользовательский RxDelegateProxy немедленно удаляется

У меня есть сторонняя библиотека с методами делегирования. Но мне нравится использовать RX, поэтому я должен создать RxDelegateProxy для получения обратных вызовов делегата через RX.

Вот мой собственный класс DelegateProxy:

extension Reactive where Base:GalleryController {

  var selectedImages:Observable<(GalleryController, [Image])> {
    let proxy = RxGalleryDelegateProxy.createProxy(for: self.base)
    return proxy.imageSubject.asObservable()
  }

}

private class RxGalleryDelegateProxy: DelegateProxy<GalleryController, GalleryControllerDelegate>, DelegateProxyType, GalleryControllerDelegate {

  private var _imageSubject: PublishSubject<(GalleryController, [Image])>?

  public weak fileprivate(set) var galleryController: GalleryController?

  internal var imageSubject: PublishSubject<(GalleryController, [Image])> {
    if let subject = _imageSubject {
      return subject
    }

    let subject = PublishSubject<(GalleryController, [Image])>()
    _imageSubject = subject

    return subject
  }

  static func currentDelegate(for object: GalleryController) -> GalleryControllerDelegate? {
    return object.delegate
  }

  static func setCurrentDelegate(_ delegate: GalleryControllerDelegate?, to object: GalleryController) {
    object.delegate = delegate
  }

  static func registerKnownImplementations() {
    self.register { RxGalleryDelegateProxy(parentObject: $0) }
  }

  private init(parentObject: GalleryController) {
    self.galleryController = castOrFatalError(parentObject)
    super.init(parentObject: parentObject, delegateProxy: RxGalleryDelegateProxy.self)
  }

  func galleryController(_ controller: GalleryController, didSelectImages images: [Image]) {
    if let subject = _imageSubject {
      subject.on(.next((controller, images)))
    }

    self._setForwardToDelegate(galleryController(controller, didSelectImages: images), retainDelegate: true)
  }

  deinit {
    _imageSubject?.on(.completed)
  }

}

В моем UIViewController я подписываюсь на:

final class PhotoLibraryViewController: UIViewController {

  private let _bag = DisposeBag()

  override func viewDidLoad() {
    super.viewDidLoad()

    let gallery = GalleryController()
    present(gallery, animated: true, completion: nil)

    gallery.rx.selectedImages
      .debug("--------")
      .observeOn(MainScheduler.instance)
      .subscribe(onNext: { (controller, images) in
        print("\(images)")
      }, onError: { (error) in
        DDLogError("Error:\n\(error)")
      })
      .disposed(by: _bag)

  }

}

Но все, что я получаю в выводе консоли через .debug("--------"), это:

2018-01-09 20:05:14.814: -------- -> subscribed
2018-01-09 20:05:14.817: -------- -> Event completed
2018-01-09 20:05:14.817: -------- -> isDisposed

Итак, мой объект сразу же удаляется сразу после создания. Что я сделал не так?


person user3742622    schedule 09.01.2018    source источник
comment
Можете ли вы предоставить больше контекста? Я подозреваю, что и proxy, и _bag выпускаются слишком рано.   -  person Maxim Volgin    schedule 10.01.2018
comment
Привет! Обновлено. _bag просто приватный let _bag = DisposeBag(). Но как насчет прокси?   -  person user3742622    schedule 10.01.2018
comment
хорошо, тогда, вероятно, метод прокси-сервера deinit вызывается, когда переменная proxy выходит за пределы области видимости. попробуйте переместить его в более широкий диапазон и посмотрите, будет ли это иметь какое-либо значение.   -  person Maxim Volgin    schedule 10.01.2018
comment
Я буду стараться. Но я полагал, что сумка при сохранении подписки будет удерживать proxydelegate.   -  person user3742622    schedule 10.01.2018
comment
Неа. Это не помогло. (   -  person user3742622    schedule 10.01.2018


Ответы (1)


Ваш объект gallery создается внутри viewDidLoad(), поэтому после завершения viewDidLoad() вызывается метод deinit из gallery и он уничтожается.

Переместите свой объект gallery из viewDidLoad():

final class PhotoLibraryViewController: UIViewController {

  private let _bag = DisposeBag()
  let gallery = GalleryController()

  override func viewDidLoad() {
    super.viewDidLoad()

    present(gallery, animated: true, completion: nil)

    gallery.rx.selectedImages
      .debug("--------")
      .observeOn(MainScheduler.instance)
      .subscribe(onNext: { (controller, images) in
        print("\(images)")
      }, onError: { (error) in
        DDLogError("Error:\n\(error)")
      })
      .disposed(by: _bag)

  }

}
person xandrefreire    schedule 31.01.2018
comment
Это должен быть правильный ответ, поскольку вы создаете экземпляр GalleryController внутри метода viewDidLoad, поэтому после завершения viewDidLoad экземпляр GalleryController также будет деинициализирован. - person Anirudha Mahale; 27.09.2019