zoukankan      html  css  js  c++  java
  • [RxSwift]4.1.5、Signal

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(let_us_code)
    ➤博主域名:https://www.zengqiang.org
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/13569308.html
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    热烈欢迎,请直接点击!!!

    进入博主App Store主页,下载使用各个作品!!!

    注:博主将坚持每月上线一个新app!!!

    Signal 和 Driver 相似,唯一的区别是,Driver 会对新观察者回放(重新发送)上一个元素,而 Signal 不会对新观察者回放上一个元素。

    他有如下特性:

    • 不会产生 error 事件
    • 一定在 MainScheduler 监听(主线程监听)
    • 共享附加作用

    现在,我们来看看以下代码是否合理:

    let textField: UITextField = ...
    let nameLabel: UILabel = ...
    let nameSizeLabel: UILabel = ...
    
    let state: Driver<String?> = textField.rx.text.asDriver()
    
    let observer = nameLabel.rx.text
    state.drive(observer)
    
    // ... 假设以下代码是在用户输入姓名后运行
    
    let newObserver = nameSizeLabel.rx.text
    state.map { $0?.count.description }.drive(newObserver)
    

    这个例子只是将用户输入的姓名绑定到对应的标签上。当用户输入姓名后,我们创建了一个新的观察者,用于订阅姓名的字数。那么问题来了,订阅时,展示字数的标签会立即更新吗?

    嗯、、、 因为 Driver 会对新观察者回放上一个元素(当前姓名),所以这里是会更新的。在对他进行订阅时,标签的默认文本会被刷新。这是合理的。

    那如果我们用 Driver 来描述点击事件呢,这样合理吗?

    let button: UIButton = ...
    let showAlert: (String) -> Void = ...
    
    let event: Driver<Void> = button.rx.tap.asDriver()
    
    let observer: () -> Void = { showAlert("弹出提示框1") }
    event.drive(onNext: observer)
    
    // ... 假设以下代码是在用户点击 button 后运行
    
    let newObserver: () -> Void = { showAlert("弹出提示框2") }
    event.drive(onNext: newObserver)
    

    当用户点击一个按钮后,我们创建一个新的观察者,来响应点击事件。此时会发生什么?Driver 会把上一次的点击事件回放给新观察者。所以,这里的 newObserver 在订阅时,就会接受到上次的点击事件,然后弹出提示框。这似乎不太合理。

    因此像这类型的事件序列,用 Driver 建模就不合适。于是我们就引入了 Signal:

    ...
    
    let event: Signal<Void> = button.rx.tap.asSignal()
    
    let observer: () -> Void = { showAlert("弹出提示框1") }
    event.emit(onNext: observer)
    
    // ... 假设以下代码是在用户点击 button 后运行
    
    let newObserver: () -> Void = { showAlert("弹出提示框2") }
    event.emit(onNext: newObserver)
    

    在同样的场景中,Signal 不会把上一次的点击事件回放给新观察者,而只会将订阅后产生的点击事件,发布给新观察者。这正是我们所需要的。

    结论

    一般情况下状态序列我们会选用 Driver 这个类型,事件序列我们会选用 Signal 这个类型。

  • 相关阅读:
    反射+注解:excel2module
    RSA签名
    base642photo
    maven命令
    201421123042 《Java程序设计》第14周学习总结
    201421123042 《Java程序设计》第13周学习总结
    201421123042 《Java程序设计》第12周
    201421123042 《Java程序设计》第10周学习总结
    201421123042 《Java程序设计》第9周学习总结
    201421123042 《Java程序设计》第8周学习总结
  • 原文地址:https://www.cnblogs.com/strengthen/p/13569308.html
Copyright © 2011-2022 走看看