美文网首页
RxSwift - 代理转成可观察序列(DelegateProx

RxSwift - 代理转成可观察序列(DelegateProx

作者: love_ll | 来源:发表于2020-06-20 09:33 被阅读0次

  delegate在iOS的开发中随处可见,不管是系统库还是第三方库都能看到delegate。在学习使用RxSwift的过程中发现如果项目组使用了RxSwift那如果再用delegate就和RxSwift的链式编程方式不相称了。解决办法就是对代理进行一层Rx封装。其中RxCocoa就是对Cocoa做了大量的封装。下面我们就自定义代理来演示最基本的对自定义代理进行Rx封装。

一、定义自己的代理

  1.定义一个最简单的代理MyDelegate,这个代理里面有两个代理方法printNum和printStr,其中printStr是可选的。

@objc public protocol MyDelegate{
  
    func printNum(num: Int)
    
    @objc optional func printStr(str: String)
    
}

  2.再定义一个类MyClass,MyClass类持有一个MyDelegate类型属性,还有两个方法,start和stop

class MyClass: NSObject {
    
    public weak var delegate: MyDelegate?
    
    var timer: Timer?
    
    override init() {}
    
    func start() {
        timer = .init(timeInterval: 1, repeats: true, block: { _ in
            self.delegate?.printNum(num: 1)
            self.delegate?.printStr?(str: "这是字符串")
        })
        RunLoop.current.add(timer!, forMode: .default)
        timer?.fire()
    }
    
    func stop() {
        timer?.invalidate()
    }
}

二、实现自定义代理的委托

  1.DelegateProxy 是代理委托,我们可以将它看作是代理的代理。
  2.DelegateProxy 的作用是做为一个中间代理,他会先把 delegate 对象保存一份,然后拦截 delegate的方法。
  3.实现自定义代理的委托需要继承 DelegateProxy ,同时它还要遵守 DelegateProxyType 和 MyDelegate 协议。

class RxMyDelegateProxy: DelegateProxy<MyClass,MyDelegate>,DelegateProxyType,MyDelegate {
    
    
    init(my: MyClass) {
        super.init(parentObject: my, delegateProxy: RxMyDelegateProxy.self)
    }
    
    static func registerKnownImplementations() {
        self.register { (parent) -> RxMyDelegateProxy in
            RxMyDelegateProxy(my: parent)
        }
    }
    
    static func currentDelegate(for object: MyClass) -> MyDelegate? {
        return object.delegate
    }
    
    static func setCurrentDelegate(_ delegate: MyDelegate?, to object: MyClass) {
        object.delegate = delegate
    }
    
    override func setForwardToDelegate(_ delegate: DelegateProxy<MyClass, MyDelegate>.Delegate?, retainDelegate: Bool) {
        super.setForwardToDelegate(delegate, retainDelegate: true)
    }
    
    internal lazy var nums = PublishSubject<Int>()

    func printNum(num: Int) {
        _forwardToDelegate?.printNum(num: num)
        self.nums.onNext(num)
    }

    deinit {
        self.nums.onCompleted()
    }
}

三、对MyClass类进行Rx扩展

  我们对 MyClass 进行Rx 扩展,作用是将MyClass与前面创建的代理委托关联起来,将自定义的 delegate 方法转为可观察序列。

extension Reactive where Base: MyClass{
    
    var delegate: DelegateProxy<MyClass,MyDelegate>{
        return RxMyDelegateProxy.proxy(for: base)
    }
    
    var nums: Observable<Int>{
        return RxMyDelegateProxy.proxy(for: base).nums.asObservable()
    }
    
    var strs: Observable<String>{
        return delegate.methodInvoked(#selector(MyDelegate.printStr(str:))).map {
            return $0[0] as! String
        }
    }
    
}

四、使用

let my: MyClass = MyClass()
my.start()
my.rx.nums.subscribe(onNext: { (num) in
     print(num)
}).disposed(by: disposeBag)

my.rx.strs.subscribe(onNext: { (str) in
     print(str)
}).disposed(by: disposeBag)

Demo

相关文章

网友评论

      本文标题:RxSwift - 代理转成可观察序列(DelegateProx

      本文链接:https://www.haomeiwen.com/subject/arsbxktx.html