美文网首页
RxSwift初探

RxSwift初探

作者: 凌云01 | 来源:发表于2020-09-27 15:18 被阅读0次

RxSwift(ReactiveX for Swift),ReactiveX的Swift版本 ,是一个简化异步编程的框架,实现了函数响应式编程,事件与对象紧密联系,业务流清晰,便于管理。在RxSwift中,所有异步操作(事件)和数据流均被抽象为可观察序列的概念。
流程为:
创建序列 -> 订阅序列 -> 发送信号 -> 信号接收

一、准备工作

要求

  • Xcode 11.x
  • Swift 5.x

对于Xcode 10.3.1及更低版本,请使用RxSwift 5.0.1

安装

  • 1、 CocoaPods方式的安装
# Podfile
use_frameworks!

target 'YOUR_TARGET_NAME' do
    pod 'RxSwift', '~> 5'
    pod 'RxCocoa', '~> 5'
end
  • 2、命令行

    • pod repo update
    • pod install
  • 3、 导入模块

    • import RxSwift
    • import RxCocoa

模块说明

  • RxSwift:Rx标准API的Swift实现,不包括任何iOS相关的内容
  • RxCocoa:基于RxSwift,给iOS UI控件扩展了很多Rx特性

二、简单使用

1、KVO

class Person: NSObject {
   @objc dynamic var name: String = "abc"
}

fileprivate func kvoTest() {
      let person = Person()
      person.rx.observeWeakly(String.self, "name").subscribe(onNext: { (value) in
         print(value as Any
           }).disposed(by: disposeBag)
 }

输出结果:Optional("abc")

2 、 UIButton 事件响应

//2 : UIButton 事件响应
    func buttonTest() {
        let btn = UIButton()
        btn.rx.tap.subscribe(onNext: { (_) in
            print("点击事件")
        })
        
    }
/*点进去看源码,tap默认为TouchUpInside. */
extension Reactive where Base : UIButton {

    /// Reactive wrapper for `TouchUpInside` control event.
    public var tap: RxCocoa.ControlEvent<Void> { get }
}
//那么其他类型Event呢
btn.rx.controlEvent(.touchUpOutside).subscribe(onNext: { (_) in
     print("点击事件")
})

输出结果:点击事件

3 、UITextFiled 键盘内容监听

func textFieldTest() {
        let tf = UITextField()
        tf.rx.text.orEmpty.asDriver().drive(onNext: { (str) in
            print("tf值:\(str)")
            }).disposed(by: disposeBag)
        
        // orEmpty,防空处理
    }

4 、UIScrollView ContentOffser监听

let scrollView = UIScrollView()
scrollView.rx.contentOffset
   .subscribe(onNext: { [weak self](content) in
       print(scrollView.contentOffset.y)
   })
.disposed(by: disposeBag)

5 、手势监听

let tap = UITapGestureRecognizer()
let label = UILabel()
label.addGestureRecognizer(tap)
label.isUserInteractionEnabled = true
tap.rx.event.subscribe(onNext: { (tap) in
    print(tap.view)
})
.disposed(by: disposeBag)

6 、通知

NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification)
    .subscribe(onNext: { (noti) in
        print(noti)
    })
.disposed(by: disposeBag)

7 、定时器

let timer = Timer()
timer = Observable.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
    print(num)
}).disposed(by: disposeBag)

8 、网络(URLSession)

let url = URL(string: "https://www.baidu.com")
//        原本写法
//        URLSession.shared.dataTask(with: url!) { (data, response, error) in
//            print(String.init(data:data!,encoding: .utf8))
//        }.resume()
        
URLSession.shared.rx.response(request: URLRequest(url: url!))
   .subscribe(onNext: { (response,data) in
       print(response)
   }).disposed(by: disposeBag)

三、RxSwift

  • 上面例子中为什么都可以 ‘.rx’呢?
public protocol ReactiveCompatible { /// 定义了一个协议,意味着实现了协议的都会有rx
    /// Extended type
    associatedtype ReactiveBase

    @available(*, deprecated, renamed: "ReactiveBase")
    typealias CompatibleType = ReactiveBase

    /// Reactive extensions.
    static var rx: Reactive<ReactiveBase>.Type { get set }

    /// Reactive extensions.
    var rx: Reactive<ReactiveBase> { get set }
}


import class Foundation.NSObject

/// Extend NSObject with `rx` proxy.
extension NSObject: ReactiveCompatible { }/// 因为NSObject遵循了以上协议,所以NSObject及其子类都可以 .rx
  • RxSwift 的核心角色

    • Observable:负责发送事件(Event), 可监听序列
    • Observer:负责订阅Observable,监听Observable发送的事件(Event)
Observable & Observer
enum Event<Element>  {
    case next(Element)      // next element of a sequence
    case error(Swift.Error) // sequence failed with error
    case completed          // sequence terminated successfully
}
  • Event有三种:
    • next: 携带具体数据
    • error:携带错误信息,表示Observable终止,不会再发出事件
    • completed:表示Observable终止,不会再发出事件

Observable 可以用于描述元素异步产生的序列,所有的事物都可以看作是序列,生活中许多事物都可以通过它来表示。


image
image
image

四、RxSwift核心逻辑

//1:创建序列
let observable = Observable<Int>.create { observer in
       // 3:发送信号
        observer.onNext(1)
        observer.onCompleted()
        return Disposables.create()
}


//2:订阅信息
let _ = ob.subscribe(onNext: { (text) in
            print("订阅到:\(text)")    //text从哪里来的?
        }, onError: { (error) in
            print("error: \(error)")    //error从哪里来的?
        }, onCompleted: {
            print("完成")
        }) {
            print("销毁")
}

以上便是一个从创建,到订阅,发送,接收,销毁的序列 全过程。

思考:订阅信号中的onNext闭包里面的“text”、onError闭包里面的“error”从哪里来的呢?

从订阅中心observer,一直在用的序列,序列内部的代码是不曾看到的。为什么从序列闭包里面的发出信号,订阅信号的闭包里面能够订阅到?

那么接下来看一步一步的执行过程:
1、先来看Observable.create
首先Cmd+点击create

extension ObservableType {
    // MARK: create

    /**
     Creates an observable sequence from a specified subscribe method implementation.

     - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html)

     - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method.
     - returns: The observable sequence with the specified implementation for the `subscribe` method.
     */
    public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
        return AnonymousObservable(subscribe)
    }
}

看到了啥,第一个就是ObservableTypecreate方法,有人说我们找的是observablecreate方法,这里怎么是ObservableType呢?
方法查找流程:首先Cmd+点击Observable

public class Observable<Element> : ObservableType {
    init() {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
    }
    
    public func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        rxAbstractMethod()
    }
    
    public func asObservable() -> Observable<Element> {
        return self
    }
    
    deinit {
#if TRACE_RESOURCES
        _ = Resources.decrementTotal()
#endif
    }
}

我们可以看到Observable继承ObservableType

查看源码发现:我们所写的Observable.create其实就是return了一个AnonymousObservable对象的构造方法,也就是返回了一个AnonymousObservable对象。这个对象中储存了我们发送的事件,需要回调的处理。

next:-> 找到AnonymousObservable继续探索


image.png
image

Observable.create我们知道做了什么,继续->
ob.subscribe Cmd+点击subscribe进去

 public func subscribe(onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            let disposable: Disposable
            
            、、、
            
            let observer = AnonymousObserver<Element> { event in  //创建observer,event从AnonymousObserver构建而来

                
                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {  //对next、error、completed、disposed四个闭包进行初始化
                case .next(let value): //只要观察者调用了.next事件,就会调用订阅事件.onNext
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),/*回调了当前序列(即ob)的_subscribeHandler闭包,
AnonymousObservable类里面没有subscrib方法,去他的父类Producer中查找,调用子类的实现*/
                disposable
            )
    }
//AnonymousObserver类
final class AnonymousObserver<ElementType> : ObserverBase<ElementType> {
    typealias Element = ElementType
    
    typealias EventHandler = (Event<Element>) -> Void
    
    private let _eventHandler : EventHandler
    
    init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self._eventHandler = eventHandler    //保存了包含事件的闭包
    }
 
    override func onCore(_ event: Event<Element>) {
        return self._eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}
 
//asObservable方法定义
 public func asObservable() -> Observable<E> {
     return self
 }
 
//Producer类
class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }
 
    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
        ...
}

至此:从创建序列 -> 订阅序列 -> 发送信号 -> 信号接收整个流程我们已经分析完毕。
可以参考以下流程图:

image

应用补充:

let observable = Observable<Int>.create { observer in
        observer.onNext(1)
        observer.onCompleted()
        return Disposables.create()
}
//等价于
observable = Observable.just(1) 
observable = Observable.of(1) 
observable = Observable.from([1])

var observable = Observable<Int>.create { observer in
     observer.onNext(1)
     observer.onNext(2)
     observer.onNext(3)
     observer.onCompleted()
     return Disposables.create() 
}

// 等价于 
observable = Observable.of(1, 2, 3) 
observable = Observable.from([1, 2, 3])

相关文章

  • RxSwift

    一、RxSwift初探

  • RxSwift-初探

    RxSwift-初探RxSwift核心逻辑-源码分析RxSwift-Observable序列的创建方式RxSwif...

  • RXSwift 初次探索

    RXSwift的最初探索 iOS 中 我们常用到的函数式编程 oc中的RAC 和 swift中的RXSwift 是...

  • RxSwift-初探

    就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!RxSwift-初探RxSwift核心逻辑-源码分析...

  • RxSwift-高阶函数(上)

    就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!RxSwift-初探RxSwift核心逻辑-源码分析...

  • RxSwift-高阶函数(下)

    就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!RxSwift-初探RxSwift核心逻辑-源码分析...

  • RxSwift初探

    RxSwift(ReactiveX for Swift),ReactiveX的Swift版本 ,是一个简化异步编程...

  • RxSwift 初探

    RxSwift 简介 ReactiveX(简写: Rx) 是一个函数式响应式编程的基础框架,可以帮助我们简化编程。...

  • 初探RxSwift

    demo链接 根据自己对RxSwift的理解写了一个登陆以及验证码倒计时 Observer 一个可以被观察的对象被...

  • RxSwift学习--核心逻辑再探

    前言 通过上一篇内容RxSwift学习--核心逻辑初探,对RxSwift有了些初步的认知,下面通过源码来看一下Rx...

网友评论

      本文标题:RxSwift初探

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