Swift5.0 - day13 - 响应式编程

简介: Swift5.0 - day13 - 响应式编程

一、响应式编程


  • 1.1、响应式编程(Reactive Programming,简称RP)
    响应式编程是一种编程范式,于1997年提出,可以简化异步编程,提供更优雅的数据绑定,一般与函数式融合在一起,所以也会叫做:函数响应式编程(Functional Reactive Programming,简称FRP)
  • 1.2、响应式编程比较著名的、成熟的响应式框架
  • (1)、ReactiveCocoa,简称RAC,有Objective-C、Swift版本
    官网
    github
  • (2)、ReactiveX,简称Rx,有众多编程语言的版本,比如RxJava、RxKotlin、RxJS、RxCpp、RxPHP、RxGo、RxSwift等等
    官网
    github


二、RxSwift



  • 2.1、RxSwift(ReactiveX for Swift),ReactiveX的Swift版本
    RxSwift 源码
    RxSwift中文文档
    建议:RxSwift 是一个比较重的框架,用到它可以说整个项目都可离不开它,与 RAC 差不多
  • 2.2、 RxSwift 在github上已经有详细的安装教程,这里只演示CocoaPods方式的安装


// 第一步
cd 项目
// 第二步 生成Podfile文件
pod init   
// 第三步,用Xcode打开Podfile文件,导入RxSwift
platform :ios, '9.0'
target '项目名称' do
    use_frameworks!
    pod 'RxSwift', '~> 5'
    pod 'RxCocoa', '~> 5'
end
// 第四步 自动导入RxSwift
pod install

提示:项目名称就是 target_name

  • 2.3、导入 RxSwift


import RxSwift
import RxCocoa

模块说明

  • RxSwift:Rx标准API的Swift实现,不包括任何iOS相关的内容
  • RxCocoa:基于RxSwift,给iOS UI控件扩展了很多Rx特性
  • 2.4、RxSwift 的核心角色
  • Observable:负责发送事件(Event)
  • Observer:负责订阅Observable,监听Observable发送的事件(Event)


image.png


public enum Event<Element> {
     /// Next element is produced. 
     case next(Element)
     /// Sequence terminated with an error.
     case error(Swift.Error)
     /// Sequence completed successfully.
     case completed
}
  • Event有3种
  • next: 携带具体数据
  • error: 携带错误信息,表明Observable终止,不会再发出事件
  • completed: 表明Observable终止,不会再发出事件


  • 2.5、创建、订阅 Observable  一


let observable = Observable<Int>.create { observer in
      observer.onNext(1)
      observer.onCompleted()
      return Disposables.create()
}
observable.subscribe { (event) in
      switch event {
      case .next(let element):
          print(element)
      case .error(let error):
          print(error)
      case .completed:
          print("completed")
      }
  }

上面的observable创建等价于下面的

  • let observable = Observable.just(1)   // just后面是一个整体,可以是数组,如:Observable.just([1,2,3])
  • let observable = Observable.of(1)
  • let observable = Observable.from([1])

订阅 observable.subscribe 还可以写为如下的表达式

observable.subscribe(onNext: { (element) in
    print(element)
}, onError: { (error) in
    print(error)
}, onCompleted: {
    print("completed")
})
  • 如果我们只想 subscribe 执行一次可以加上 dispose(),也就是subscribe的返回值调用 dispose(),如下,那么再次发送订阅也不会再去执行


observable.subscribe { (event) in
}.dispose()
observable.subscribe(onNext: { (element) in
     print(element)
}, onError: { (error) in
     print(error)
}, onCompleted: {
     print("completed")
}).dispose()
  • 2.6、创建、订阅 Observable  二


let bag = DisposeBag()
let label = UILabel(frame: CGRect(x: 10, y: 100, width: 100, height: 30))
label.backgroundColor = UIColor.white
self.view.addSubview(label)
let observable = Observable<Int>.timer(.seconds(3),period: .seconds(1),scheduler: MainScheduler.instance)
observable.map { "数值是\($0)" }.bind(to: label.rx.text) .disposed(by: bag)
  • 2.7、创建 observer


let observer = AnyObserver<Int>.init { event in switch event {
     case .next(let data):
        print(data)
     case .completed:
        print("completed")
     case .error(let error):
        print("error", error)
} }
Observable.just(1).subscribe(observer).dispose()
let binder = Binder<String>(label) { label, text in label.text = text }
Observable.just(1).map { "数值是\($0)" }.subscribe(binder).dispose() 
Observable.just(1).map { "数值是\($0)" }.bind(to: binder).dispose()
  • 2.8、扩展 Binder 属性


extension Reactive where Base: UIView {
    var hidden: Binder<Bool> {
       Binder<Bool>(base) { view, value in
           view.isHidden = value
       } 
    }
}
let observable = Observable<Int>.interval(.seconds(1),
                                    scheduler: MainScheduler.instance)
observable.map { $0 % 2 == 0 }.bind(to: button.rx.hidden).disposed(by: bag)
  • 2.9、传统状态的监听,在开发中经常要对各种状态进行监听,传统的常见监听方案有
  • KVO
  • Target-Action
  • Notification
  • Delegate pBlock Callback
  • 传统方案经常会出现错综复杂的依赖关系、耦合性较高,还需要编写重复的非业务代码


  • 2.10、RxSwift的状态监听一
  • button 事件的监听


button.rx.controlEvent(UIControl.Event.touchUpInside).subscribe(onNext: { (sender) in
    print("点击了target,tag=\(sender)")
}).disposed(by: bag)

提示:如果仅仅是点击事件我们可以使用 button.rx.tap


  • tableview 数据的绑定监听


let data = Observable.just([ Person(name: "Jack", age: 10), Person(name: "Rose", age: 20)])
data.bind(to: tableView.rx.items(cellIdentifier: "cell")) { row, person, cell in
    cell.textLabel?.text = [person.name](person.name)
    cell.detailTextLabel?.text = "\(person.age)" 
}.disposed(by: bag)
tableView.rx.modelSelected(Person.self) .subscribe(onNext: { person in
    print("点击了", [person.name](person.name)) 
}).disposed(by: bag)
tableView.rx.itemSelected.subscribe(onNext: { path in 
    print("点击了", path) 
}).disposed(by: bag)

提示:如果cell使我们自定义的,那么 .items(cellIdentifier: "cell")),后面的type要写:.items(cellIdentifier: "cell", cellType: 自定义cell的名字.self))


  • 2.11、RxSwift的状态监听二


class Dog: NSObject {
    @objc dynamic var name: String?
}
dog.rx.observe(String.self, "name").subscribe(onNext: { name in
    print("name is", name ?? "nil")
}).disposed(by: bag)
[dog.name](dog.name) = "larry"
[dog.name](dog.name) = "wangwang"
  • 2.12、RxSwift的状态监听三:通知,下面是进入后台的通知


NotificationCenter.default.rx.notification(UIApplication.didEnterBackgroundNotification).subscribe(onNext: { notification in
       print("APP进入后台", notification) 
}).disposed(by: bag)
  • 2.12、既是Observable,又是Observer


[Observable.just(0.8).bind(to](Observable.just(0.8).bind(to): slider.rx.value).dispose()
  • 滑块的value


slider.rx.value.map { "当前数值是:\($0)"}.bind(to: textField.rx.text).disposed(by: bag)
  • textField内容的监听


textField.rx.text.subscribe(onNext: { text in
   print("text is", text ?? "nil")
}).disposed(by: bag)
  • 诸如UISlider.rx.value、UTextField.rx.text这类属性值,既是Observable,又是Observer ,它们是 RxCocoa.ControlProperty 类型


  • 2.13、Disposable
  • 每当Observable被订阅时,都会返回一个Disposable实例,当调用Disposable的dispose,就相当于取消订阅
  • 在不需要再接收事件时,建议取消订阅,释放资源。有3种常见方式取消订阅
  • 立即取消订阅(一次性订阅)


observable.subscribe { event in
     print(event)
}.dispose()
  • 当bag销毁(deinit)时,会自动调用Disposable实例的dispose


observable.subscribe { event in
     print(event)
}.disposed(by: bag)
  • self销毁时(deinit)时,会自动调用Disposable实例的dispose


let _ = observable.takeUntil(self.rx.deallocated).subscribe { event in
    print(event)
}


最后:航歌里面有更多的RxSwift的用法,大家可以学习

目录
相关文章
|
7月前
|
NoSQL 关系型数据库 数据库
Swift 服务器框架对比
Swift 服务器框架对比
116 0
|
8天前
|
JavaScript 前端开发 Swift
开发语言漫谈-Swift
swift就是个语言的大杂烩
|
7月前
|
调度 Swift 开发者
Swift中的异步编程方式
说到异步编程,我们很容易想到的编译回调。无论是需要并行的耗时任务,还是允许串行的简单任务,都通过回调的方式返回结果。回调也是在开发中使用最为广泛的一种异步编程方式。回想一下,通常的网络请求,文件操作等函数都会提供一个回调参数。回调使用起来虽然方便,但其并不利于进行程序流程的控制,仅仅从代码层面看,也很难组织清楚代码的执行顺序和逻辑。
54 0
|
Swift C语言
深入浅出Swift(3)—— 函数
深入浅出Swift(3)—— 函数
62 0
|
JavaScript 前端开发 Scala
Swift5.0 - day11- 函数式编程
Swift5.0 - day11- 函数式编程
66 0
|
Swift
(一)swift的基本学习
(一)swift的基本学习
137 0
|
存储 编译器 Swift
17.Swift学习之类
类介绍 Swift虽然推荐面向协议编程,但其也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象(类的实例) Swift中用class关键字定义类 定义语法 class 类名 { // 定义属性和方法 } 举例 class ...
944 0
|
Swift C语言
2.Swift学习之初探
Playground是什么? 从Xcode6开始出现(Swift开始出现) 翻译为:操场/游乐场 对于学习Swift基本语法非常方便 所见即所得(快速查看结果) 语法特性发生改变时,可以快速查看 Playground Swift最...
828 0
|
JavaScript Java iOS开发
1.Swift学习之介绍
简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 Mac OS 和 iOS 应用程序 Apple WWDC 2014 横空出世 Swift 历史 2010 年 7 月,苹果开发者工具部门总监 Chris Lattner...
1102 0