③、iOS-RxSwift核心逻辑,RxSwift实战案例,Observable的继承链,Observable订阅的流程、OnNext的流程、AnonymousObservableSink业务逻辑

RxSwift系列
①、RxSwift基础控件的使用、RxSwif-Tableview的使用、RxSwift-SectionTableview结合RxDataSources的使用、RxSwift 网络请求封装的使用
②、RxSwift函数式响应编程思想,RxSwift-KVO、Button、UITextField、ScrollView、手势、通知、定时器、网络请求的使用
③、iOS-RxSwift核心逻辑,RxSwift实战案例,Observable的继承链,Observable订阅的流程、OnNext的流程、AnonymousObservableSink业务逻辑用
④、RxSwift的Timer、Observable的创建、RxSwiftUI控件(UIDatePicker、UIButton、UISwitch、UISlider、UIStepper)在实际开发的使用

推荐网站
RxSwift官方文档
RxSwift-Github源码
RxSwift的操作符

Demo
Demo-①、RxSwift基础控件的使用、RxSwif-Tableview的使用、RxSwift-SectionTableview结合RxDataSources的使用、RxSwift 网络请求封装的使用
Demo-②、RxSwift函数式响应编程思想,RxSwift-KVO、Button、UITextField、ScrollView、手势、通知、定时器、网络请求的使用-1
Demo-②、RxSwift函数式响应编程思想,RxSwift-KVO、Button、UITextField、ScrollView、手势、通知、定时器、网络请求的使用-2-Observable

本文章知识点

RxSwift核心流程走向图

RxSwift核心流程

RxSwift核心逻辑

①、RxSwift在实战开发中的应用-以账号密码的控制为例子

RxSwift在实战开发中的应用-以账号密码的控制为例子

1.需求
最终效果 :
1.用户名必须大于5位 ,如果不满足,则提醒
2.密码必须大于6位,如果不满足,则提醒
3.如果用户名不满足条件。密码不然输入
4.用户名和密码同时符合条件的时候 才能点击登录按钮

分析

1.用户名必须大于5位 ,如果不满足,则提醒
fileprivate let minUsernameLength = 5
  let usernameVaild = usernameTextFiled.rx.text.orEmpty
            .map{ (text) -> Bool in
                // 如果输入的数量 > 5 就能继续往下执行
                return text.count >= minUsernameLength
            }
     // usernameVaild 绑定到 usernameValidLabel的显示, usernameValidLabel是否显示是根据usernameVaild的值
        usernameVaild.bind(to: usernameValidLabel.rx.isHidden)
            .disposed(by: disposeBag)

2.密码必须大于6位
        let passwordVaild = passwordTextFiled.rx.text.orEmpty
            .map{ (text) -> Bool in
                // 如果输入的数量 > 5 就能继续往下执行
                return text.count >= minPasswordLength
            }
        passwordVaild.bind(to: passwordValidLabel.rx.isHidden)
            .disposed(by: disposeBag)

3.如果用户名不满足条件。密码不然输入
        // 继续绑定 如果不输入账号 密码也不给输入
        usernameVaild.bind(to: passwordTextFiled.rx.isEnabled)
            .disposed(by: disposeBag)
4.用户名和密码同时符合条件的时候 才能点击登录按钮
        // 决定按钮  --- buton.rx.isenalbe
        //{$0 && $1} 只有第一个参数 和 第二个参数 同时满足才输出
        Observable.combineLatest(usernameVaild,passwordVaild) {$0 && $1}
        .bind(to: loginBtn.rx.isEnabled)
        .disposed(by: disposeBag)
        
        
        loginBtn.rx.tap.subscribe(onNext: {(btn) in
            print("点击")
        })
            .disposed(by: disposeBag)

ViewController

import UIKit
import RxCocoa
import RxSwift

fileprivate let minUsernameLength = 5
fileprivate let minPasswordLength = 6

class ViewController: UIViewController {

    @IBOutlet weak var usernameTextFiled: UITextField!
    @IBOutlet weak var usernameValidLabel: UILabel!
    @IBOutlet weak var passwordTextFiled: UITextField!
    @IBOutlet weak var passwordValidLabel: UILabel!
    @IBOutlet weak var loginBtn: UIButton!
    
    var disposeBag = DisposeBag.init()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        checkInput()
    }
    
    func checkInput(){
        /**
         * 当用户输入用户名时,如果用户名不足 5个字就给出红色提示语,并且无法输入密码,当用户名符合要求时才可以输入密码。
         
         * 同样的当用户输入的密码不到 5 个字时也给出红色提示语。 当用户名和密码有一个不符合要求时底部的绿色按钮不可点击,只有当用户名和密码同时有效时按钮才可点击。
         
         * 当点击绿色按钮后弹出一个提示框,这个提示框只是用来做演示而已。
         */
         
        // usernameTextFiled.rx.text序列 -- usernameVaild 序列
        // map 操作符将源 Observable 的每个元素应用你提供的转换方法,然后返回含有转换结果的 Observable。
        let usernameVaild = usernameTextFiled.rx.text.orEmpty
            .map{ (text) -> Bool in
                // 如果输入的数量 > 5 就能继续往下执行
                return text.count >= minUsernameLength
            }
        
        // usernameVaild 绑定到 usernameValidLabel的显示, usernameValidLabel是否显示是根据usernameVaild的值
        usernameVaild.bind(to: usernameValidLabel.rx.isHidden)
            .disposed(by: disposeBag)
        
        // 继续绑定 如果不输入账号 密码也不给输入
        usernameVaild.bind(to: passwordTextFiled.rx.isEnabled)
            .disposed(by: disposeBag)
        
        
        
        let passwordVaild = passwordTextFiled.rx.text.orEmpty
            .map{ (text) -> Bool in
                // 如果输入的数量 > 5 就能继续往下执行
                return text.count >= minPasswordLength
            }

        passwordVaild.bind(to: passwordValidLabel.rx.isHidden)
            .disposed(by: disposeBag)
        
        // 决定按钮  --- buton.rx.isenalbe
        //{$0 && $1} 只有第一个参数 和 第二个参数 同时满足才输出
        Observable.combineLatest(usernameVaild,passwordVaild) {$0 && $1}
        .bind(to: loginBtn.rx.isEnabled)
        .disposed(by: disposeBag)
        
        
        loginBtn.rx.tap.subscribe(onNext: {(btn) in
            print("点击")
        })
            .disposed(by: disposeBag)

            

    }


}


②、RxSwift核心逻辑-Observable的继承链-创建

0.Observable继承链

Observable继承链
在这里插入图片描述

1.Observablecreate使用

        // 1. 创建序列
        let ob  = Observable<Any>.create{(observer) -> Disposable in
            // 3.发送信号
            observer.onNext("发送信号")
            observer.onCompleted()
//            observer.onError(NSError.init(domain: "YHError", code: 10086, userInfo: nil))
            return Disposables.create()
        }
        // 2. 订阅信号
        let _ = ob.subscribe(onNext: { (text) in
            print("订阅到了 \(text)")
        }, onError: {(error) in
            print("error: \(error)")
        }, onCompleted: {
            print("完成了")
        }, onDisposed: {
            print("销毁了")
        })

2.Observablecreate底层逻辑总结。

carete使用到了AnonymousObservableAnonymousObservable继承了ProducerProducer继承了ObservableObservable遵循了ObservableType,ObservableType是一个协议、用来扩展功能的

    public static func create(_ subscribe: @escaping (AnyObserver<Element>) -> Disposable) -> Observable<Element> {
        AnonymousObservable(subscribe)
    }
final private class AnonymousObservable<Element>: Producer<Element>
class Producer<Element>: Observable<Element>
//  Observable
public class Observable<Element> : ObservableType {
    // 性能优化 做了一个引用计数+1
    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> { self }
    
    // 性能优化 做了一个引用计数-1
    deinit {
#if TRACE_RESOURCES
        _ = Resources.decrementTotal()
#endif
    }
}

public protocol ObservableType: ObservableConvertibleType

3.为什么RxSwfit UI控件能转换成Observable,做到万物皆Observable序列

因为控件的value是一个ControlProperty 但是ControlProperty遵循了 ControlPropertyType协议,而ControlPropertyType是遵循ObservableType协议的 。所以能转换成 Observable

   // 万物皆序列
        // value 只是 ControlProperty 不是 Observable
        // 但是 ObservableType遵循了ObservableType 协议 可以转成 Observable
        UISwitch().rx.value.asObservable()

③、RxSwift核心逻辑-Observable的订阅

0.订阅底层的流程图

订阅内部流程

1.subscribeon

所有的事件 称之为一个事件 On事件

    public func subscribe(_ on: @escaping (Event<Element>) -> Void) -> Disposable {
        let observer = AnonymousObserver { e in
            on(e)
        }
        return self.asObservable().subscribe(observer)
    }

2.subscribeonNext

事件分开订阅 有 onNextonErroronCompletedonDisposed

其中public func subscribe( onNext: ((Element) -> Void)? = nil函数的参数的 Element.是从外部传递进来的 比如 let ob = Observable<Any>.create{(observer) -> Disposable in
Any 就充当内部的Element

    /**
     Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
     
     - parameter onNext: Action to invoke for each element in the observable sequence.
     - parameter onError: Action to invoke upon errored termination of the observable sequence.
     - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
     - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
     gracefully completed, errored, or if the generation is canceled by disposing subscription).
     - returns: Subscription object used to unsubscribe from the observable sequence.
     */
    public func subscribe(
        onNext: ((Element) -> Void)? = nil,
        onError: ((Swift.Error) -> Void)? = nil,
        onCompleted: (() -> Void)? = nil,
        onDisposed: (() -> Void)? = nil
    ) -> Disposable {
            let disposable: Disposable
            
            if let disposed = onDisposed {
                disposable = Disposables.create(with: disposed)
            }
            else {
                disposable = Disposables.create()
            }
            
            #if DEBUG
                let synchronizationTracker = SynchronizationTracker()
            #endif
            
            let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : []
            
            let observer = AnonymousObserver<Element> { event in
                
                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {
                case .next(let value):
                    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),
                disposable
            )
    }

3.subscribeAnonymousObserver

我们找到AnonymousObserver,去查看他的类 。他也有一次继承链的关系,继承于ObserverBase
那么ObserverBase需要什么核心消息呢 就是on

let observer = AnonymousObserver<Element> { event in


----

final class AnonymousObserver<Element>: ObserverBase<Element> {
    typealias EventHandler = (Event<Element>) -> Void
    
    private let eventHandler : EventHandler
    
    // 保存闭包
    init(_ eventHandler: @escaping EventHandler) {
    // 这个也是Rx里面的引用计数 但是这个类不是 序列所以要分开写
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self.eventHandler = eventHandler
    }

    override func onCore(_ event: Event<Element>) {
        self.eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

ObserverBase

具备了最核心的功能 ononcoredispose
相当于 有 订阅、调度者、销毁功能

class ObserverBase<Element> : Disposable, ObserverType {
	// Element 就是相当于 确定类型
    private let isStopped = AtomicInt(0)

    func on(_ event: Event<Element>) {
        switch event {
        case .next:
            if load(self.isStopped) == 0 {
                self.onCore(event)
            }
        case .error, .completed:
            if fetchOr(self.isStopped, 1) == 0 {
                self.onCore(event)
            }
        }
    }

    func onCore(_ event: Event<Element>) {
        rxAbstractMethod()
    }

    func dispose() {
        fetchOr(self.isStopped, 1)
    }
}

ObserverBase的ObserverType协议

协议的实现 在具体类里面实现 也就是在 ObserverBase类里面实现

public protocol ObserverType {
    /// The type of elements in sequence that observer can observe.
    /// 协议的关联类型
    associatedtype Element

    /// Notify observer about sequence event.
    ///
    /// - parameter event: Event that occurred.
    /// 协议的关联方法 -  在 ObserverBase 里面实现了
    func on(_ event: Event<Element>)
}

4.subscribe的最终的实现是在AnonymousObserver ,还是在AnonymousObserver的父类Producer里面

Producer里面实现。具体的实现在子类
Producer 继承 ObserverBase 毫无影响

class Producer<Element>: Observable<Element> {
    override init() {
        super.init()
    }

    override func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            // The returned disposable needs to release all references once it was disposed.
            let disposer = SinkDisposer()
            let sinkAndSubscription = self.run(observer, cancel: disposer)
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }
        else {
            return CurrentThreadScheduler.instance.schedule(()) { _ in
                let disposer = SinkDisposer()
                let sinkAndSubscription = self.run(observer, cancel: disposer)
                disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

                return disposer
            }
        }
    }

    func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
        rxAbstractMethod()
    }
}

④、RxSwift核心逻辑-ProducerAnonymousObservableSink管子

1.从Producersubscribe跟踪到run.进入AnonymousObservableSink管子的run

发送内部的流程

sink管子 初始化的时候 包含了 observer 然后sink.run(AnonymousObservable)
管子里面包含了 订阅者、序列、销毁
从上面的Producer也包含了 订阅、调度者、销毁
管子 包含了 订阅者 销毁者 序列 + 调度环境 - 相当于manager

2.继续查看AnonymousObservableSink业务逻辑层

 func run(_ parent: Parent) -> Disposable {
        parent.subscribeHandler(AnyObserver(self))
    }

 AnonymousObservable.subscribeHandler(AnyObserver(self))
 //  AnyObserver 是一个结构体
 AnyObserver(self) - AnyObserver(sink) 最终是由管子请发送信号 "发送信号"
 //   AnyObserver(sink) 初始化 会执行到
     public init<Observer: ObserverType>(_ observer: Observer) where Observer.Element == Element {
        self.observer = observer.on
    }
//  AnyObserver.observer 是一个函数块(on) --- 订阅者已经完毕 -- sink管子
//  AnyObserver.onNext  -- 订阅者


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇夜iOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值