使用RxSwift扩展目标动作方法

时间:2018-11-21 08:04:51

标签: swift rx-swift reactive

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( ...

2 个答案:

答案 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+RxBundle+Rx

如果您需要提供代理委托,事情会变得更加复杂,但这超出了此问题的范围。