swift

Swift - RxSwift的使用详解61(sendMessa

2018-05-29  本文已影响664人  八级大狂风AM

一、基本介绍

1,sendMessage 与 methodInvoked 的区别

(1)在之前的几篇文章中,我用到了 methodInvoked 这个 Rx 扩展方法,其作用是获取代理方法执行后产生的数据流。

(2)除了 methodInvoked 外,还有个 sentMessage 方法也有同样的作用,它们间只有一个区别:

2,实现原理

(1)其原理简单说就是利用 Runtime 消息转发机制来转发代理方法。同时在调用返回值为空的代理方法的前后分别产生两种数据流。

(2)比如最开始的代理为 A,然后我们把代理改为 AProxy,并把 A 设置为 AProxy_forwardToDelegate。这样所有的代理方法将会变成到达 AProxy,接着 AProxy对这些方法进行如下操作:

二、使用样例

我们分别通过 sendMessage 以及 methodInvoked 方法来获取 selector 对应的 Observable,并将它们与原方法做比较,看看执行的先后顺序。

(注意:两个样例中 selector 都不是代理方法,但不影响效果的演示。)

样例1:拦截 VC 的 viewWillAppear 方法

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //使用sentMessage方法获取Observable
        self.rx.sentMessage(#selector(ViewController.viewWillAppear(_:)))
            .subscribe(onNext: { value in
                print("1")
            })
            .disposed(by: disposeBag)
         
        //使用methodInvoked方法获取Observable
        self.rx.methodInvoked(#selector(ViewController.viewWillAppear(_:)))
            .subscribe(onNext: { value in
                print("3")
            })
            .disposed(by: disposeBag)
    }
     
    //默认的viewWillAppear方法
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("2")
    }
}

运行结果如下:

样例2:拦截自定义方法

import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //使用sentMessage获取方法执行前的序列
        self.rx.sentMessage(#selector(ViewController.test))
            .subscribe(onNext: { value in
                print("1:\(value[0])")
            })
            .disposed(by: disposeBag)
         
        //使用methodInvoked获取方法执行后的序列
        self.rx.methodInvoked(#selector(ViewController.test))
            .map({ (a) in
                return try castOrThrow(String.self, a[0])
            })
            .subscribe(onNext: { value in
                print("3:\(value)")
            })
            .disposed(by: disposeBag)
         
        //调用自定义方法
        test("hangge.com")
    }
     
    //自定义方法
    @objc dynamic func test(_ value:String) {
        print("2:\(value)")
    }
}
 
//转类型的函数(转换失败后,会发出Error)
fileprivate func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
    guard let returnValue = object as? T else {
        throw RxCocoaError.castingError(object: object, targetType: resultType)
    }
    return returnValue
}

运行结果如下:

RxSwift使用详解系列
原文出自:www.hangge.com转载请保留原文链接

上一篇下一篇

猜你喜欢

热点阅读