美文网首页
RxSwift4.0Driver的使用

RxSwift4.0Driver的使用

作者: 数字d | 来源:发表于2020-01-31 17:40 被阅读0次

Driver提供一种简便的方法在UI层编写响应式代码,简单来说就是序列驱动应用程序,如果序列满足如下特征,就可以使用Driver
1.不会产生error事件
2.一定在主线程监听MainScheduler
3.共享状态变化shareReplayLatestWhileConnected

使用Driver的场景:
1.通过CoreData来驱动UI
2.使用一个UI元素的值(绑定)来驱动另一个UI元素的值
3.与普通的操作系统驱动程序一样,如果出现序列错误,应用程序将停止响应用户输入
4.在主线程上观察到这些元素也是必要的,因为UI元素和应用程序逻辑通常不是线程安全的
5.此外,使用构建Driver的可观察序列,它是共享状态变化

Demo功能是,当TextField输入数据时候(一个UI元素),Lab(另一个UI元素)的text和Btn(另一个UI元素)的Tittle内容发生更改.

这里解释下最基本的实现方法,dealWithData方法先将UitextField的输入的值映射成序列,通过创建序列result,然后对序列result进行订阅,在订阅到序列的逻辑中刷新UI.

dealWithData方法,将字符串转化为序列

    func dealWithData(inputText:String) -> Observable<Any> {

//这里的请求网络是模拟的,并没有真的请求,只是将数据的textField的内容做了更改,实际开发中可以自行修改
        print("请求网络\(Thread.current)")
        
        return Observable<Any>.create { (ob) -> Disposable in
            if inputText == "1234" {
                ob.onError(NSError.init(domain: "log.error", code: 10096, userInfo: nil))
            }
            
            DispatchQueue.global().async {
                print("发送之前的内容:\(Thread.current)")
                ob.onNext("已经输入:\(inputText)")
                ob.onCompleted()
//               子线程刷新UI会crash
//                self.btn.setTitle("123", for: .normal)
            }
            return Disposables.create()
        }
    }

在viewDidLoad中来实现序列的映射

       let result = tf.rx.text.skip(1)
           .flatMap{[weak self](input) -> Observable<Any> in
                return (self?.dealWithData(inputText:input ?? ""))!
  }

在viewDidLoad中实现订阅

       result.subscribe(onNext:{ (element) in
            print("订阅到\(element)")
        })
        result.subscribe(onNext:{ (element) in
            print("订阅到:\(Thread.current) --- \(element)")
        })

以上代码即可实现所需的功能,但是是存在问题的。
问题1:被订阅的次数是多少,网络请求的次数就有多少,这里浪费网络请求资源和带宽
问题2.订阅到的实现是在子线程中的,如果再订阅到的时候刷新UI,代码会crash
问题3.关于自定义的错误回调,也要进行处理。即可以显示错误,但是不能让应用因错误而崩溃。

解决方案:
调用函数

.share(replay: 1, scope: .whileConnected)

这样写网络请求就只执行一次

.observeOn(MainScheduler.instance) 

这样写订阅到的时候就是主线程

接下来是错误事件的处理,这样处理就会将错误处理发出来,而不是直接闪退,减少因为error而出现的闪退

 .catchErrorJustReturn("检测到了error事件")

序列创建综合实现

        let result = tf.rx.text.skip(1)
            .flatMap{[weak self](input) -> Observable<Any> in
                return (self?.dealWithData(inputText:input ?? ""))!
                    .observeOn(MainScheduler.instance)
                .catchErrorJustReturn("检测到了error事件")
        }.share(replay: 1, scope: .whileConnected)

按照上面综合实现的代码可以解决上面提到的三个问题。功能的实现到此结束。

接下来是优化写法方案:

序列的创建方案实现,将oberverable序列转化成driver类型来实现序列的创建

//可选项orEmpty
        let result = tf.rx.text.orEmpty
            .asDriver()
            .flatMap {
                return self.dealWithData(inputText: $0)
                .asDriver(onErrorJustReturn: "检测到错误事件")
                
        }

序列订阅和UI绑定

        result.map{"长度\(($0 as! String).count)"}
            .drive(self.lab.rx.text)
        result.map{"长度\($0 as! String)"}
            .drive(self.btn.rx.title())

按照driver序列的实现

代码拉取地址:

https://gitee.com/xgkp/hFunction.git

实现

图示UI

1

相关文章

  • RxSwift4.0Driver的使用

    Driver提供一种简便的方法在UI层编写响应式代码,简单来说就是序列驱动应用程序,如果序列满足如下特征,就可以使...

  • iconfont的使用(下载使用)

    1、下载文件 2、在生命周期中引入项目 beforeCreate () { var domModule = ...

  • Gson的使用--使用注解

    Gson为了简化序列化和反序列化的过程,提供了很多注解,这些注解大致分为三类,我们一一的介绍一下。 自定义字段的名...

  • 记录使用iframe的使用

    默认记录一下----可以说 这是我第一次使用iframe 之前都没有使用过; 使用方式: 自己开发就用了这几个属...

  • with的使用

    下面例子可以具体说明with如何工作: 运行代码,输出如下

  • this的使用

    什么是this? this是一个关键字,这个关键字总是返回一个对象;简单说,就是返回属性或方法“当前”所在的对象。...

  • this的使用

    JS中this调用有几种情况 一:纯粹的函数调用 这是函数的最通常用法,属于全局性调用,因此this就代表全局对象...

  • ==的使用

    积累日常遇到的编码规范,良好的编码习惯,持续更新。。。 日常使用==用于判断的时候,习惯性将比较值写前面,变量写后...

  • this的使用

    1.默认绑定,就是函数立即执行。 函数立即执行就是指向window,但是如果是node环境,就是指向全局conso...

  • %in% 的使用

    写在前面:From 生信技能书向量难点之一:%in% 难点 (1)== 与 %in% 的区别== 强调位置,x和对...

网友评论

      本文标题:RxSwift4.0Driver的使用

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