6

RxSwift / RxCocoa では、デリゲート (UIScrollViewDelegateまたは などCLLocationManagerDelegate) のリアクティブ ラッパーを作成して、特定のデリゲート メソッドの Rx オブザーバブル シーケンスを有効にすることができます。

UIApplicationDelegateメソッドにこれを実装しようとしていますapplicationDidBecomeActive:

これまでに試したことは非常に単純でDelegateProxy、RxCocoa に含まれているサブクラスに似ています。

DelegateProxyサブクラスを作成しました:

class RxUIApplicationDelegateProxy: DelegateProxy, UIApplicationDelegate, DelegateProxyType {

    static func currentDelegateFor(object: AnyObject) -> AnyObject? {
        let application: UIApplication = object as! UIApplication
        return application.delegate
    }

    static func setCurrentDelegate(delegate: AnyObject?, toObject object: AnyObject) {
        let application: UIApplication = object as! UIApplication
        application.delegate = delegate as? UIApplicationDelegate
    }
}

および Rx 拡張機能UIApplication:

extension UIApplication {
    public var rx_delegate: DelegateProxy {
        return proxyForObject(RxUIApplicationDelegateProxy.self, self)
    }

    public var rx_applicationDidBecomeActive: Observable<Void> {
        return rx_delegate.observe("applicationDidBecomeActive:")
            .map { _ in
                return
            }
    }
}

私の AppDelegate では、オブザーバブルにサブスクライブします。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // the usual setup
    // and then:
    application.rx_applicationDidBecomeActive
        .subscribeNext { _ in
            print("Active!")
        }
        .addDisposableTo(disposeBag)

    return true
}

アプリを起動すると「アクティブ!」印刷され、RxCocoa の_RXDelegateProxy_クラスで次のクラッシュが発生します。

ここに画像の説明を入力

問題が何であるかを知っている人はいますか?または、誰かが次のようなものを正常に実装しましたrx_applicationDidBecomeActiveか?

4

1 に答える 1

9

RxSwift とメモリ管理に関しては、非常に難しい問題のようです。

の既定の実装でDelegateProxyTypeは、デリゲート プロキシ (この場合はRxUIApplicationDelegateProxy)delegateのインスタンスが に設定されますUIApplication

また、元AppDelegateのプロパティを呼び出されるプロパティとして保存するforwardToDelegateため、すべてのデリゲート メソッドを引き続き渡すことができます。

問題は、新しいアプリ デリゲートが設定されている場合:

 application.delegate = delegate as? UIApplicationDelegate

元のものは割り当て解除されています!でオーバーライドすることで確認できdeinitますAppDelegate。理由はこの回答で説明されています。また、プロパティforwardToDelegateのタイプが であるため、プロパティがassign割り当て解除されたオブジェクトを指しているため、アプリがクラッシュします。

そのための回避策を見つけました。推奨される方法かどうかはわかりませんので、注意してください。DelegateProxyTypeからメソッドをオーバーライドできますRxUIApplicationDelegateProxy

  override func setForwardToDelegate(delegate: AnyObject?, retainDelegate: Bool) {
    super.setForwardToDelegate(delegate, retainDelegate: true)
  }

通常の状況では、保持サイクルにつながるため、デリゲートを保持する必要はありません。しかし、この特別なケースでは、これは問題ではありません。UIApplicationオブジェクトは、アプリケーションが動作している間ずっと存在します。

于 2016-02-25T20:31:37.590 に答える