将 UIApplicationDelegate 方法转换为 RxSwift Observables
Transform UIApplicationDelegate methods into RxSwift Observables
在 RxSwift / RxCocoa 中,您可以为委托创建反应式包装器(例如 UIScrollViewDelegate
或 CLLocationManagerDelegate
),以便为某些委托方法启用 Rx 可观察序列。
我正在尝试为 UIApplicationDelegate
方法实现此 applicationDidBecomeActive:
到目前为止,我尝试的方法非常简单,类似于 RxCocoa 中包含的 DelegateProxy
subclasses。
我创建了我的 DelegateProxy
子class:
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 中,我订阅了 observable:
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
}
当我启动我的应用程序时 "Active!" 被打印出来,然后我在 RxCocoa 的 _RXDelegateProxy_
中遇到以下崩溃 class:
有人知道问题出在哪里吗?或者有没有人成功实施过 rx_applicationDidBecomeActive
?
RxSwift 和内存管理似乎是一个非常棘手的问题。
DelegateProxyType
的默认实现将委托代理实例(在本例中为 RxUIApplicationDelegateProxy
)设置为 UIApplication
的 delegate
。
它还将原始 AppDelegate
存储为一个名为 forwardToDelegate
的 属性,因此所有委托方法仍然可以传递给它。
问题是,当设置新的应用委托时:
application.delegate = delegate as? UIApplicationDelegate
原版已解除分配!您可以通过覆盖 AppDelegate
中的 deinit
来检查它。 this answer 中解释了原因。因为 属性 forwardToDelegate
是 assign
类型,你的应用程序崩溃,因为 属性 指向一个释放的对象。
我已经找到解决方法。我不确定这是否是推荐的方式,所以请注意。您可以在 RxUIApplicationDelegateProxy
:
中覆盖 DelegateProxyType
中的方法
override func setForwardToDelegate(delegate: AnyObject?, retainDelegate: Bool) {
super.setForwardToDelegate(delegate, retainDelegate: true)
}
在正常情况下,您不希望保留委托,因为它会导致保留循环。但在这种特殊情况下,这不是问题:您的 UIApplication
对象将一直存在,而您的应用程序仍然存在。
在 RxSwift / RxCocoa 中,您可以为委托创建反应式包装器(例如 UIScrollViewDelegate
或 CLLocationManagerDelegate
),以便为某些委托方法启用 Rx 可观察序列。
我正在尝试为 UIApplicationDelegate
方法实现此 applicationDidBecomeActive:
到目前为止,我尝试的方法非常简单,类似于 RxCocoa 中包含的 DelegateProxy
subclasses。
我创建了我的 DelegateProxy
子class:
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 中,我订阅了 observable:
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
}
当我启动我的应用程序时 "Active!" 被打印出来,然后我在 RxCocoa 的 _RXDelegateProxy_
中遇到以下崩溃 class:
有人知道问题出在哪里吗?或者有没有人成功实施过 rx_applicationDidBecomeActive
?
RxSwift 和内存管理似乎是一个非常棘手的问题。
DelegateProxyType
的默认实现将委托代理实例(在本例中为 RxUIApplicationDelegateProxy
)设置为 UIApplication
的 delegate
。
它还将原始 AppDelegate
存储为一个名为 forwardToDelegate
的 属性,因此所有委托方法仍然可以传递给它。
问题是,当设置新的应用委托时:
application.delegate = delegate as? UIApplicationDelegate
原版已解除分配!您可以通过覆盖 AppDelegate
中的 deinit
来检查它。 this answer 中解释了原因。因为 属性 forwardToDelegate
是 assign
类型,你的应用程序崩溃,因为 属性 指向一个释放的对象。
我已经找到解决方法。我不确定这是否是推荐的方式,所以请注意。您可以在 RxUIApplicationDelegateProxy
:
DelegateProxyType
中的方法
override func setForwardToDelegate(delegate: AnyObject?, retainDelegate: Bool) {
super.setForwardToDelegate(delegate, retainDelegate: true)
}
在正常情况下,您不希望保留委托,因为它会导致保留循环。但在这种特殊情况下,这不是问题:您的 UIApplication
对象将一直存在,而您的应用程序仍然存在。