class A{
func addTarget(target: Any, action: Selector)
}
假设我没有可用的A类源(框架)。我该如何反应性地扩展此类,以通过Observable发出Rx事件?
我可以创建一个仅通过PublishSubject转发事件的类,但是在那种情况下,我不会创建Reactive扩展,而是通过代理类来完成它。
let a = A()
let del = CustomClassThatAddsItselfAsATarget(a)
del.event.subscribe( ...
代替
let a = A()
a.rx.event.subscribe( ...
答案 0 :(得分:1)
这是一个有趣的探索。我从下面介绍了如何在RxCocoa中设置UIControl。
回答您的后续问题:
哪个对象会将自身作为目标(addTarget方法)添加到基础?
您必须创建一个专门用于执行此操作的类。我将其命名为ATarget
。
谁保留了该对象?
您使对象符合Disposable
,然后将其保留直到被处置。
extension Reactive where Base: A {
var event: Observable<A> {
return Observable.create { [weak a = self.base] observer in
guard let a = a else {
observer.on(.completed)
return Disposables.create()
}
let aTarget = ATarget(a: a, callback: { a in
observer.on(.next(a))
})
return Disposables.create(with: aTarget.dispose)
}
.takeUntil(deallocated)
}
}
class ATarget: NSObject, Disposable {
typealias Callback = (A) -> Void
let selector: Selector = #selector(ATarget.eventHandler)
weak var a: A?
var callback: Callback?
init(a: A, callback: @escaping Callback) {
self.a = a
self.callback = callback
super.init()
a.addTarget(target: self, action: selector)
}
@objc func eventHandler() {
if let callback = self.callback, let a = self.a {
callback(a)
}
}
func dispose() {
self.a?.removeTarget(target: self)
self.callback = nil
}
}
答案 1 :(得分:0)
RxCocoa
和大多数其他基于RxSwift
的框架采用以下方法-
public extension Reactive where Base: TheOriginalClass {
有关实现的示例,请参见CKRecord+Rx或Bundle+Rx。
如果您需要提供代理委托,事情会变得更加复杂,但这超出了此问题的范围。