中国建设银行演示网站,长页网站,wordpress 文件夹权限,php与mysql网站开发...1. 什么是RxSwift
RxSwift是Swift函数响应式编程的一个开源库#xff0c;由Github的ReactiveX组织开发、维护
RxSwift的目的是#xff1a;让数据/事件流 和 异步任务能够更方便的序列化处理#xff0c;能够使用Swift进行响应式编程
RxSwift本质上还是观察者模式#xff…1. 什么是RxSwift
RxSwift是Swift函数响应式编程的一个开源库由Github的ReactiveX组织开发、维护
RxSwift的目的是让数据/事件流 和 异步任务能够更方便的序列化处理能够使用Swift进行响应式编程
RxSwift本质上还是观察者模式并且是一个响应式的并且可以序列化的
观察者模式
观察者模式包括KVO、通知等
爸爸妈妈照看观察宝宝 其中宝贝就是被观察者 爸爸妈妈就是观察者或者说是订阅者 只要被观察者宝宝发出来某些事件比如哭声、叫声则被称为事件通知到订阅者 此时订阅者就可以做响应的工作
RxSwift做了什么
RxSwift把我们程序中的每一个操作都看成一个事件 比如一个TextField中的文本改变、一个按钮被点击、一个网络请求结束等 每一个事件源就可以看成一个管道也就是sequence
比如TextField当我们改变里面的文本的时候这个TextField就会不断的发出事件 从他的sequence中不断流出我们只需要监听这个sequence每流出一个事件就做相应的处理
同理Button也是一个sequence每点击一次就流出一个事件
理解Observable和Observer 2. RxSwift简单体验
RxSwift监听按钮的点击RxSwift监听UITextField的文字改变RxSwift改变Label中的文字RxSwift监听对象属性改变RxSwift监听UIScrollView的滚动…
//导入RxSwift
import RxSwift
import RxCocoa按钮监听
原始方法 button.addTarget(self, action: #selector(button1Click), for: .touchUpInside)
使用RxSwift的方法
self.button.rx.tap.subscribe { (event: EventVoid) inprint(event)
}上述方法会有一个标黄的警告Result of call to ‘subscribe’ is unused 修改方法 private lazy var disposeBag: DisposeBag DisposeBag()self.button.rx.tap.subscribe { (event: EventVoid) inprint(event)
}.disposed(by: disposeBag)监听UITextField文字的改变
方法一传统方法
略
方法二
self.view.addSubview(self.textField)
self.textField.frame CGRect(x: 200, y: 300, width: 100, height: 40)
self.textField.rx.text.subscribe { (event: EventString?) inprint(event.element)//获取信息
}.disposed(by: disposeBag)这种方法获取的event有两个Optional包裹着使用起来不方便
方法三
self.textField.rx.text.subscribe { (myString: String?) inprint(myString)//获取的是Optional类型
} onError: { error inprint(error)
} onCompleted: {print(onCompleted)
} onDisposed: {print(onDisposed)
}.disposed(by: disposeBag)以上可以简化
self.textField.rx.text.subscribe { (myString: String?) inprint(myString)//获取的是Optional类型
}.disposed(by: disposeBag)监听Label中的文字
UITextField文字输入然后Label显示输入的文字
方法一
self.textField.rx.text.subscribe { (myString: String?) inprint(myString)self.myTitleLabel.text myString
}.disposed(by: disposeBag)self.view.addSubview(myTitleLabel)
myTitleLabel.frame CGRect(x: 100, y: 210, width: 200, height: 40)方法二
self.textField.rx.text.bind(to: myTitleLabel.rx.text).disposed(by: disposeBag)self.view.addSubview(myTitleLabel)
myTitleLabel.frame CGRect(x: 100, y: 210, width: 200, height: 40)RxSwift的KVO
self.view.addSubview(myTitleLabel)
myTitleLabel.frame CGRect(x: 100, y: 210, width: 200, height: 40)myTitleLabel.rx.observe(String.self, text).subscribe { (str: String?) inprint(str)
}.disposed(by: disposeBag)RxSwift监听UIScrollView的滚动
self.view.addSubview(scrollView)
scrollView.frame CGRect(x: 100, y: 280, width: 200, height: 150)
scrollView.rx.contentOffset.subscribe { (point: CGPoint) inprint(point)
}.disposed(by: disposeBag)3. RxSwift常见操作
Never、Empty、Just、Of、From、Create、Range、RepeatElement
Never什么都不执行
///never啥事没有
let observableNever ObservableString.never()
observableNever.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)Empty创建一个空的sequence只能发出一个completed事件 //只执行completed
let observableEmpty ObservableString.empty()
observableEmpty.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)打印结果
completedJust是创建一个sequence只能发出一种特定的事件并且能正常结束 也就是特定事件可以监听complete事件可以监听 ///Just只执行特定类型complete
let observableJust Observable.just(123)//Int类型
observableJust.subscribe { (event: EventInt) in//EventInt相对应print(event)
}.disposed(by: disposeBag)打印结果
next(123)
completedOf可以执行特定类型complete创建一个sequence可以发出多个事件信号
///Of: 可以执行特定类型多个事件complete
let observableOf Observable.of(1, 2, 3, 6)
observableOf.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)打印结果
next(1)
next(2)
next(3)
next(6)
completedFrom从数组中创建sequence
///From: 可以执行数组complete
let observableFrom Observable.from([123, 234, 345])
observableFrom.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)打印结果
next(123)
next(234)
next(345)
completedCreate可以自定义可观察的sequenceCreate操作符传入一个观察者observer然后调用observer的onNextonCompleted和onError方法返回一个可观察的observable序列
///Create: 可以自定义观察事件complete
let observableCreate createObservableFunc()
observableCreate.subscribe { (event: EventAny) inprint(event)
}.disposed(by: disposeBag)///创建自定义的createObservable
private func createObservableFunc() - ObservableAny {return Observable.create { (observer: AnyObserverAny) inobserver.onNext(123)observer.onNext(321)//注意Disposables带sreturn Disposables.create()}
}
打印结果
next(123)
next(321)如果想要completed则需要加上observer.onCompleted() Range创建一个sequence会发出这个范围中的从开始到结束的所有事件
///Range: 可以执行某个范围内的
let observableRange Observable.range(start: 3, count: 3)
observableRange.subscribe { (event: EventInt) inprint(event)
}.disposed(by: disposeBag)打印结果
next(3)
next(4)
next(5)
completedRepeatElement重复执行某个事件
///RepeatElement: 重复执行某个事件
let observableRepeatElement Observable.repeatElement(2)
observableRepeatElement.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag) 执行以上代码恭喜你程序干崩溃了 可以加上take(count)
///RepeatElement: 重复执行某个事件
let observableRepeatElement Observable.repeatElement(2)
observableRepeatElement.take(3).subscribe { (event: EventString) inprint(event)}.disposed(by: disposeBag)打印结果
next(2)
next(2)
next(2)
completed4. RxSwift中Subjects
Subjects是什么
Subject是Observable和Observer之间的桥梁 一个Subject既是一个Observable也是一个Observer 即可以监听事件也可以发出事件
Observable监听事件 Observer发出事件
PublishSubject、ReplaySubject、BehaviorSubject、BehaviorRelay
PublishSubject
当订阅PublishSubject的时候只能接收订阅他之后发生的事件 subject.onNext()发出onNext事件对应的还有OnError()和onCompleted()事件
let publishSub PublishSubjectString()
//不接收
publishSub.onNext(0)//订阅事件
publishSub.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)//只能接收订阅后的事件
publishSub.onNext(1)
publishSub.onNext(2)
publishSub.onNext(3)
publishSub.onCompleted()打印结果
next(1)
next(2)
next(3)
completedReplaySubject
当你订阅ReplaySubject的时候你可以接收到订阅他之后的事件 但也可以接受订阅他之前发出的事件接受前面几个事件取决与bufferSize的大小
//bufferSize决定订阅前接收几个。订阅后的都可以接收到
let replaySbu ReplaySubjectString.create(bufferSize: 2)
replaySbu.onNext(1-0)
replaySbu.onNext(1-1)
replaySbu.onNext(1-2)
//订阅事件
replaySbu.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)
replaySbu.onNext(1-3)
replaySbu.onNext(1-4)
replaySbu.onNext(1-5)
replaySbu.onCompleted()打印结果
next(1-1)
next(1-2)
next(1-3)
next(1-4)
next(1-5)
completedBehaviorSubject
BehaviorSubject会接受到订阅之前的最后一个事件
//behaviorSbu接收订阅前最后一个。订阅后的都可以接收到
let behaviorSbu BehaviorSubject(value: 1)
behaviorSbu.onNext(2-0)
behaviorSbu.onNext(2-1)
behaviorSbu.onNext(2-2)
//订阅事件
behaviorSbu.subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)
behaviorSbu.onNext(2-3)
behaviorSbu.onNext(2-4)
behaviorSbu.onNext(2-5)
behaviorSbu.onCompleted()打印结果
next(2-2)
next(2-3)
next(2-4)
next(2-5)
completedBehaviorRelay
behaviorRelay是BehaviorSubject的一个包装箱 使用的时候需要调用asObservable()拆箱里面的value是一个BehaviorSubject 如果Variable准备发出事件不需要onNext这种方式而是直接修改对象的value即可
let behaviorRelay BehaviorRelay(value: 3-1)
behaviorRelay.accept(3-2)
behaviorRelay.accept(3-3)
behaviorRelay.asObservable().subscribe { (event: EventString) inprint(event)
}.disposed(by: disposeBag)
behaviorRelay.accept(3-4)
behaviorRelay.accept(3-5)打印结果
next(3-3)
next(3-4)
next(3-5)RxSwift在UITableView的使用
方法一
Model:
struct HeroModel: Codable {var name: Stringvar age: Stringvar description: Stringenum CodingKeys: String, CodingKey {case namecase agecase description describe}
}ViewModel:
class HeroViewModel {var herosObserrable: BehaviorRelay[HeroModel] {var herosArray: [HeroModel] [HeroModel]()guardlet path Bundle.main.path(forResource: RxSwiftData, ofType: json),let jsonData try? Data(contentsOf: URL(fileURLWithPath: path))else {print(Error loading JSON file)return BehaviorRelay(value: [])}do {let decoder JSONDecoder()herosArray try decoder.decode([HeroModel].self, from: jsonData)for hero in herosArray {print(hero)}}catch {print(Error parsing JSON: \(error))}return BehaviorRelay(value: herosArray)}()
}
extension ViewController {fileprivate func loadData(){//获取VMlet heroVM HeroViewModel()//订阅VMheroVM.herosObserrable.asObservable().subscribe { (heros: [HeroModel]) inself.herosArray.removeAll()self.herosArray herosself.myTableView.reloadData()}.disposed(by: disposeBag)}
}extension ViewController: UITableViewDelegate, UITableViewDataSource {func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - Int {return herosArray.count}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - UITableViewCell {guard let cell tableView.dequeueReusableCell(withIdentifier: MyTableViewCell) as? MyTableViewCell else {print(Error: Could not dequeue cell as MyTableViewCell)return UITableViewCell()}cell.nameLabel.text herosArray[indexPath.row].namecell.ageLabel.text herosArray[indexPath.row].agecell.desLabel.text herosArray[indexPath.row].descriptionreturn cell}
}private lazy var myTableView: UITableView {let myTableView UITableView()myTableView.delegate selfmyTableView.dataSource selfmyTableView.register(MyTableViewCell.self, forCellReuseIdentifier: MyTableViewCell)return myTableView
}()方法二
Model、ViewModel同上
extension ViewController {fileprivate func loadData(){let heroVM HeroViewModel()//直接在这将监听的数据直接赋值heroVM.herosObserrable.asObservable().bind(to: myTableView.rx.items(cellIdentifier: MyTableViewCell, cellType: MyTableViewCell.self)){(row, hero, cell) incell.nameLabel.text hero.namecell.ageLabel.text hero.agecell.desLabel.text hero.description}.disposed(by: disposeBag)}
}