在RxSwift / RxCocoa中,您可以为委托创建一个反应式包装器(例如 UIScrollViewDelegate
或 CLLocationManagerDelegate
),以便为某些委托方法启用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中,我订阅了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_
类中遇到以下崩溃:
有谁知道问题可能是什么?或者有没有人成功实现 rx_applicationDidBecomeActive
之类的东西?
1 回答
对于RxSwift和内存管理来说,这似乎是一个非常棘手的问题 .
DelegateProxyType
的默认实现将委托代理的实例(在本例中为RxUIApplicationDelegateProxy
)设置为delegate
的delegate
.它还将原始
AppDelegate
存储为名为forwardToDelegate
的属性,因此仍可以将所有委托方法传递给它 .问题是,当设置新的app代理时:
原来的一个被解除分配!您可以通过覆盖
AppDelegate
中的deinit
来检查它 . 原因在this answer中解释 . 并且因为属性forwardToDelegate
的类型为assign
,所以当应用属性指向已释放的对象时,您的应用会崩溃 .我找到了解决方法 . 我不确定它是否是推荐的方式,所以请注意 . 您可以在
RxUIApplicationDelegateProxy
中覆盖DelegateProxyType
中的方法:在正常情况下,您不希望保留委托,因为它会导致保留周期 . 但在这种特殊情况下,这不是问题 - 您的
UIApplication
对象将存在,直到您的应用程序仍处于活动状态 .