【问题标题】:My custom RxDelegateProxy immediately disposing我的自定义 RxDelegateProxy 立即处理
【发布时间】:2018-06-18 23:33:18
【问题描述】:

我有一些具有委托方法的第三方库。但我喜欢使用 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

所以我的对象在创建后立即处理。我做错了什么?

【问题讨论】:

  • 你能提供更多的上下文吗?我怀疑 proxy_bag 发布得太早了。
  • 嗨!更新。 _bag 只是私有的 let _bag = DisposeBag()。但是代理呢?
  • 好的,那么一旦 proxy 变量超出范围,可能会调用代理的 deinit 方法。尝试将其移至更大的范围,看看是否有任何不同。
  • 我会试试的。但我相信retain订阅期间的包会持有proxydelegate。
  • 不。它没有帮助。 (

标签: ios swift delegates rx-swift rx-cocoa


【解决方案1】:

您的gallery 对象是在viewDidLoad() 内部创建的,所以一旦viewDidLoad() 完成,来自gallerydeinit 方法就会被调用并被释放。

将您的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)

  }

}

【讨论】:

  • 这应该是正确的答案,因为您正在 viewDidLoad 方法中创建 GalleryController 的实例,因此一旦完成 viewDidLoadGalleryController 的实例也将被取消初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-29
  • 2014-08-03
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多