一头扎进,RxSwift的编程风格

第一天:简单体验与RxSwift的编程风格

RxSwift扫盲

作为iOS开发者,或许你没听说过RxSwift,但是一定听说过函数式编程[Functional Programming]、响应式编程[Reactive Programming]、函数响应式编程[Functional Reactive Programming];

简书(简书搜索"Moya") http://www.jianshu.com/search?q=Moya&page=1&type=notes

概述

从 C 语言的面向过程开始,到后来的 Objective-C、C 面向对象编程,风靡了编程界几十年。后来 Java 的 Spring 框架提出了面向切面编程的思想,但是并未在 iOS 开发中流行起来。如今,码友们听得最多的应该是函数响应式编程。本文算是笔者的一个学习记录过程。

import UIKit
//导入Rx相关框架
import RxSwift
import RxCocoa

struct Music {
    let name:String
    let singer:String

    init(name:String,singer:String) {
        self.name = name
        self.singer = singer
    }
}

extension Music:CustomStringConvertible{
    var description: String {
        return "name:(name) singer:(singer)"
    }
}


struct MusicListModel {
    /*
     这里我们将 data 属性变成一个可观察序列对象(Observable Squence),
     而对象当中的内容和我们之前在数组当中所包含的内容是完全一样的。
     关于可观察序列对象在后面的文章中我会详细介绍。
     简单说就是“序列”可以对这些数值进行“订阅(Subscribe)”,有点类似于“通知(NotificationCenter)”
     */
    let data = Observable.just([
        Music(name: "无条件", singer: "陈奕迅"),
        Music(name: "你曾是少年", singer: "S.H.E"),
        Music(name: "从前的我", singer: "陈洁仪"),
        Music(name: "在木星", singer: "朴树")
        ])
}

/*
 这里我们不再需要实现数据源和委托协议了。而是写一些响应式代码,让它们将数据和 UITableView 建立绑定关系。
 */

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    /*
     DisposeBag:作用是 Rx 在视图控制器或者其持有者将要销毁的时候,自动释法掉绑定在它上面的资源。
     它是通过类似“订阅处置机制”方式实现(类似于 NotificationCenter 的 removeObserver)。
     */
    let disposeBag = DisposeBag()
    let musicArray = MusicListModel()


    override func viewDidLoad() {
        super.viewDidLoad()

        //将数据源数据绑定到tableView上
        /*
         rx.items(cellIdentifier:):这是 Rx 基于 cellForRowAt 数据源方法的一个封装。
         传统方式中我们还要有个 numberOfRowsInSection 方法,使用 Rx 后就不再需要了(Rx 已经帮我们完成了相关工作)。
         */
        musicArray.data.bind(to: tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell in
            cell.textLabel?.text = music.name
            cell.detailTextLabel?.text = music.singer
            }.disposed(by: disposeBag)

        //tableView点击响应
        /*
         rx.modelSelected: 这是 Rx 基于 UITableView 委托回调方法 didSelectRowAt 的一个封装。
         */
        tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in
            print("你选中的歌曲信息【(music)】")
        }).disposed(by: disposeBag)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}
见名知意,RxSwift 是在 Apple 推出 Swift 后,针对 Swift 语言 ReactiveX 推出 Reactive Extensions 系列一个实现库;除此之外,ReactiveX 还推出了 RxJava,RxAndroid,RxPHP 等蕴含类似思想的框架。

【RxSwift系列】RxSwift下如何实现基于MJRefresh的上下拉刷新? - 简书 http://www.jianshu.com/p/fff7ef50dbb1

RxSwift 简介

RxSwift 是 GitHub 的 ReactiveX 团队出的一套框架,针对 Swift 语言。除此之外,ReactiveX 还推出了 RxJava,RxAndroid,RxPHP 等蕴含类似思想的框架。

由代码可以看出,与官方通过MVC代理方式实现列表的数据展示和操作,RxSwift在代码上跟精简,逻辑上更加连贯。

为什么要学习RxSwift?

我们知道 C 语言的面向过程,Objective-C、C 面向对象编程, Java 的 Spring 框架提出了面向切面编程的思想,学习 RxSwift 不是学习如何使用第三方库,而是学习一种编程思想--函数响应式编程;

学习 Swift Moya(二)- Moya SwiftyJSON RxSwift - 简书 http://www.jianshu.com/p/aba7aed61afd

RxSwift 安装

如果你还没有掌握 CocoaPods,请先学习,依赖管理是学习每一种语言都需要掌握的技能。建议通过 Pods 来安装 RxSwift,在Podfile文件中引入 RxSwift 和 RxCocoa。

pod 'RxSwift'pod 'RxCocoa'

RxSwift 是 Swift 语言的函数响应式编程框架。RxCocoa 则是对苹果原声面向对象 Api 的封装。

在需要用到 RxSwift 相关内容的类里面,引入模块即可。

import RxSwiftimport RxCocoa

Why use RxSwift?

A vast majority of the code we write involves responding to external events. When a user manipulates a control, we need to write an @IBAction handler to respond. We need to observe notifications to detect when the keyboard changes position. We must provide closures to execute when URL sessions respond with data. And we use KVO to detect changes to variables. All of these various systems makes our code needlessly complex. Wouldn't it be better if there was one consistent system that handled all of our call/response code? Rx is such a system.RxSwift is the official implementation of Reactive Extensions , which exist for most major languages and platforms.

我们编写的绝大多数代码涉及对外部事件的响应。当一个用户操作控制,我们需要写一个@IBAction处理器响应。当键盘改变位置时,我们需要观察通知来检测。当URL会话响应数据时,必须提供闭包来执行。我们使用KVO的变化来检测变量。所有这些不同的系统使我们的代码不必要的复杂。如果有一个一致的系统处理我们所有的呼叫/响应代码,这不是更好吗?Rx就是这样一个系统。RxSwift是官方实现的Reactive扩展正,存在的最主要的语言和平台。

why use RxSwift?视频讲解RxSwift使用 RxSwift 进行响应式编程

jkyeo/RxMoyaMapperDemo: An object mapper demo using Moya RxSwift SwiftyJSON https://github.com/jkyeo/RxMoyaMapperDemo

RxSwift 简单应用

需求:现在界面上有两个 UIButton,我想监听它们的点击事件。

按照以往的做法,我们会首先增加按钮的点击监听,然后自定义一个方法,最后再方法内部去处理点击之后的逻辑。

// 增加点击监听button1.addTarget(self, action: #selector(clickButton1), for: .touchUpInside)button1.addTarget(self, action: #selector(clickButton2), for: .touchUpInside)

// 实现点击之后的逻辑@objc func clickButton1() { print}@objc func clickButton2() { print}

这样做可能面临的问题是:代码分离度比较高、后期代码维护费力等等。

下面来看一看用 RxSwift 来实现上述需求。

button1.rx.tap.subscribe { (event: Event< in print}

当你写下button1.rx.tap后,试图通过“.”语法把后面的语句敲出来时,会发现没有提示。

图片 1我的解决方法是重新实例化一个 UIButton,然后就可以看到代码提示,写完代码之后再替换。图片 2不知道哪位码友有更好的解决方案?

subscribe是订阅的意思,整体可以理解为订阅button1的点击事件,当按钮被点击是,通过闭包回调。这样就实现了监听按钮点击并处理点击事件的需求。但是当前代码会报一个警告:

图片 3警告:返回值没有被使用解决:

// 类里面懒加载 DisposeBag 对象fileprivate lazy var bag = DisposeBag()// 增加点击监听button1.rx.tap.subscribe { (event: Event< in print}.addDisposableTo

.addDisposableTo 的作用可以先不用理会,后面会提到,现在就当它是用来消除警告的语句。

RxSwift的优点

  • Composable 可组合,在设计模式中有一种模式叫做组合模式,你可以方便的用不同的组合实现不同的类
  • Reusable 代码可重用,原因很简单,对应RxSwift,就是一堆Obserable
  • Declarative 响应式的,因为状态不可变,只有数据变化
  • Understandable and concise 简洁,容易理解。
  • Stable 稳定,因为RxSwift写出的代码,单元测试时分方便
  • Less stateful “无”状态性,因为对于响应式编程,你的应用程序就是一堆数据流
  • Without leaks 没有泄漏,因为资源管理非常简单

GitHub约一万个Star

图片 4screen.png

用 RxSwift Moya 写出优雅的网络请求代码 - 简书 http://www.jianshu.com/p/178b6e24ba7e

RxSwift 简单应用

需求:界面上有2个 UITextField,我想监听它们的输入。

成为文本框的代理

textField1.delegate = selftextField2.delegate = self

实现文本框协议

// MARK: - UITextFieldDelegateextension ViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // 判断是哪一个输入框发生改变 if textField == textField1 { print("输入框1 改变") } else { print("输入框2 改变") } return true }}

这样做可能面临的问题:界面有多个文本框,需要每个都实现代理,并且需要判断是哪一个文本框发生了改变,维护成本比较高,代码可读性差。

先订阅 UITextField,文字输入改变时通过闭包回调。

textField1.rx.text.subscribe { (event: Event<String?>) in print(event.element)}.addDisposableTo

图片 5打印出来的结果有点吓唬人,再一看element的类型也就不足为奇了。图片 6还有另外一种写法:

textField1.rx.text.subscribe(onNext: { (str: String?) in print.addDisposableTo

图片 7

这样打印出来的东西友好了许多。

响应式编程:ReactiveCocoa vs RxSwift 选谁好?

RAC是一个已经有着3年历史的项目,从Objective-C时期开始,后来从3.0开始支持了swift(可以通过bridge在OC下使用),接着就完全停止了在Objective-C上的维护。RxSwift项目的时间短一些只有几个月(作者写的时间是15年),但是社区似乎充满了动力。关于RxSwift有一件重要的事是项目是按照 ReactiveX这个组织的规定下开发的,并且所有其他语言的Rx项目也是一样。如果学会了如何使用RxSwift,再去学习Rx.Net, RxJava 或者 RxJS就是小菜一碟,只是语言语法上的差异。这真的就是learn once, apply everywhere.

摘自没故事的卓同学

知乎上某人的回答如果项目中有oc,就用ReactiveCocoa;要是用没有,就用RxSwift咯

参考文章RxSwift 介绍一头扎进 RxSwiftRxSwift文档的中文翻译RxSwift使用教程

GitHubPageBlog/用-RxSwift-Moya-写出优雅的网络请求代码.md at master · liuduoios/GitHubPageBlog https://github.com/liuduoios/GitHubPageBlog/blob/master/source/_posts/用-RxSwift-Moya-写出优雅的网络请求代码.md

RxSwift 简单应用

需求:现在我们在上面例子的基础上,增加两个 UILabel,实时显示文本框所输入的内容。

textField1.rx.text .bind(to: label1.rx.text) .addDisposableTo

把文本输入框的值,绑定到 UILabel 上面。

如何写出最简洁优雅的网络封装 Moya RxSwift - 简书 http://www.jianshu.com/p/c1494681400b

RxSwift 简单应用

在平时的开发中,我们经常使用KVO来监听某个对象的某一属性改变。KVO 使用流程和监听按钮点击差不多,首先需要添加监听,然后覆盖系统方法进行逻辑处理。

// 对 frame 属性添加监听label1.addObserver(self, forKeyPath: "frame", options: .new, context: nil)

// 覆盖父类方法,实现监听回调override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if label1.isEqual { if keyPath == "frame" { print } }}

label1.rx.observe(CGRect.self, "frame") .subscribe(onNext: { (frame: CGRect?) in print .addDisposableTo

图片 8

observe 方法接收 2 个参数:

  1. 监听的属性的类型
  2. 监听的属性的名字

监听完毕之后,对该事件进行订阅,通过闭包形式进行回调。

除此之外,还可以直接监听属性的改变,例如:监听 UIScrollView 的偏移量。

图片 9

读到这里,算对函数响应式编程RxSwiftRxCocoa有了初步的了解和认识。

如果对你有所帮助,请点一个

本文由星彩网app下载发布于计算机编程,转载请注明出处:一头扎进,RxSwift的编程风格

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。