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在实战开发中的应用-以账号密码的控制为例子
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
继承链
1.Observable
的create
使用
// 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.Observable
的create
底层逻辑总结。
carete使用到了
AnonymousObservable
、AnonymousObservable
继承了Producer
、Producer
继承了Observable
、Observable
遵循了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.subscribe
的on
所有的事件 称之为一个事件 On事件
public func subscribe(_ on: @escaping (Event<Element>) -> Void) -> Disposable {
let observer = AnonymousObserver { e in
on(e)
}
return self.asObservable().subscribe(observer)
}
2.subscribe
的onNext
事件分开订阅 有
onNext
、onError
、onCompleted
、onDisposed
其中
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.subscribe
的AnonymousObserver
我们找到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
具备了最核心的功能
on
、oncore
、dispose
相当于 有 订阅、调度者、销毁功能
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核心逻辑-Producer
的AnonymousObservableSink
管子
1.从Producer
的subscribe
跟踪到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 -- 订阅者