ios - 将 UIApplicationDelegate 方法转换为 RxSwift Observables

标签 ios swift observable uiapplicationdelegate rx-swift

在 RxSwift/RxCocoa 中,您可以为委托(delegate)创建响应式(Reactive)包装器(例如 UIScrollViewDelegateCLLocationManagerDelegate),以便为某些委托(delegate)方法启用 Rx 可观察序列。

我正在尝试为 UIApplicationDelegate 方法applicationDidBecomeActive:

实现这个

到目前为止,我尝试的方法非常简单,类似于 RxCocoa 中包含的 DelegateProxy 子类。

我创建了我的 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
    }
}

UIApplication 的 Rx 扩展:

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_ 类中遇到以下崩溃:

enter image description here

有人知道问题出在哪里吗?或者有人成功地实现了类似 rx_applicationDidBecomeActive 的东西吗?

最佳答案

这看起来是 RxSwift 和内存管理的一个非常棘手的问题。

DelegateProxyType 的默认实现将委托(delegate)代理实例(在本例中为 RxUIApplicationDelegateProxy)设置为 delegate UIApplication.

它还将原始的 AppDelegate 存储为一个名为 forwardToDelegate 的属性,因此所有委托(delegate)方法仍然可以传递给它。

问题是,当设置新的应用委托(delegate)时:

 application.delegate = delegate as? UIApplicationDelegate

原来的那个被解除分配了!您可以通过覆盖 AppDelegate 中的 deinit 来检查它。 this answer 中解释了原因.并且因为属性 forwardToDelegateassign 类型,当属性指向已释放的对象时,您的应用程序会崩溃。

我已经找到了解决方法。我不确定这是否是推荐的方式,所以请注意。您可以在 RxUIApplicationDelegateProxy 中覆盖 DelegateProxyType 的方法:

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

在正常情况下,您不希望保留委托(delegate),因为它会导致保留周期。但在这种特殊情况下,这不是问题:您的 UIApplication 对象将一直存在,而您的应用程序仍然存在。

关于ios - 将 UIApplicationDelegate 方法转换为 RxSwift Observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35575305/

相关文章:

java - 有没有更好的方法来跟踪订阅者的变化?

javascript - knockoutjs 可观察对象绑定(bind)的可观察数组

javascript - 在 Angular 2 应用程序中返回 Observable,但仍然收到错误 : "Property ' subscribe' does not exist on type 'void'

ios - 当新版本的 iOS 应用程序可用时提醒

swift - 在 ViewController 中访问自定义单元格

swift - 捕获 Mac OS X 上的功能键

swift - 元组 Void (aka ()) 的值没有成员 "isSuperset"

ios - 使用 SLRequest 将 URL 附加到 Facebook 帖子?

ios - 圆形图上的圆角末端?苹果?

ios - 从 NSDictionary 获取对象时类型 'String' 不符合协议(protocol) 'NSCopying' 错误