RxSwift 个人学习笔记记录

文章目录

  • 一 什么是RxSwift
  • 二 RxSwift做了什么
    • 2-1简单介绍观察者设计模式
    • 2-1RxSwift做了什么
    • 2-3 简单理解Observable&Observer
  • 三 RxSwift初级操作
    • 3-1 监听事件
    • 3-2 监听文本输入框的文字改变
    • 3-3 绑定数据赋值操作
    • 3-4 KVO
  • 四 RxSwift常见操作
    • 4-1 never的obserable
    • 4-2 empty的Obserable
    • 4-3 just
    • 4-4 of
    • 4-5 from
    • 4-6 create 自定义事件 开发中常用
    • 4-7 range
    • 4-8 repeat
  • 五 RxSwift中的Subjects
    • 5-1 Subjects 是什么?
    • 5-2 PublishSubject
    • 5-3 ReplySubject
    • 5-4 BehaviorSubject
    • 5-5 Variable
  • 六 RxSwift中的变换操作
    • 6-1 map
    • 6-2 flatmap
  • 七 资源的释放
    • 7-1 dispose
    • 7-2 Dispose Bags
  • 八 RxSwift下的UITableView的使用

一 什么是RxSwift

  • RxSwift是Swift函数响应式编程的一个开源库,由GitHub的ReactiveX组织开发和维护
  • 其他语言像C#,Java 和JS也有: Rx.Net、RxJava、RxJS
  • RxSwift的目的是让数据/事件流和异步任务能够更方便的序列化处理 能够使用Swift进行响应式编程

二 RxSwift做了什么?

2-1 简单介绍观察者设计模式
  • KVO,通知,甚至代理都是观察者模式,在设计模式中他可是一个重中之重的设计模式
  • 在我们iOS开发中 很多事件的监听都是通过观察者设计模式进行监听的
2-2 RxSwift做了什么?
  • RxSwift把我们程序中每一个操作都看成一个事件
  • 比如一个TextFiled中的文本改变,一个按钮的点击,或者一个网络请求结束等,每一个事件源就可以看成一个管道,也就是Sequence
  • 比如一个TextFiled,当我们改变里边的文本的时候 这个时候TextFiled就会不断的发出事件, 从他的Sequence中不断的流出 我们只需要监听这个Sequence,每流出一个事件 就做相应的处理
  • 同理UIButton 也是一个Sequence 每点击一次就流出一个事件
image.png
2-3 简单理解Observable&Observer
image.png

三RxSwift初级操作

3-1 监听事件

        // 1 监听按钮点击
        // 要用局部的按钮 方便提示  之所以在这里备用一个局部按钮 是因为RxSwift 有什么提示很不好 局部变量就可以解决这个问题
        // let button = UIButton();
        btn1.rx.tap.subscribe { (event : Event<()>) in
            print("我是按钮我被点击了")
        }.addDisposableTo(bag)

3-2 监听文本输入框的文字改变
  // 2.1 第一种方式
        
        textFlied.rx.text.subscribe { (event : Event<String?>) in
            // element 取出这个元素  取出来的是可选类型中的可选类型 可以解包两次
            print(event.element!!)
        }.addDisposableTo(bag)
        
        // 2.1 第二种方式 onNext
        textFlied.rx.text.subscribe(onNext: { (str : String?) in
            print(str!)
        }).addDisposableTo(bag)

3-3 绑定数据赋值操作
// 老套的做法
        textFlied.rx.text.subscribe(onNext: { (str : String?) in
            self.label.text = str!            
        }).addDisposableTo(bag)

//  RxSwift推荐的做法 .bind(to: <#T##ObserverType#>) observerType 是一个协议  而UIbindObser遵守了这个协议
    textFlied.rx.text.bind(to: label.rx.text).addDisposableTo(bag)

3-4 KVO
// KVO 传统的做法
  // 1 监听属性
  lbl.addObserver(self, forKeyPath: "text", options: .new, context: nil)
// 2 代理方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print((change?[NSKeyValueChangeKey.newKey])!)
    }


// RxSwift 的做法

        label.rx.observe(String.self, "text").subscribe(onNext: { (str : String?) in            
            print(str!)            
        }).addDisposableTo(bag)        
        label.rx.observe(CGRect.self, "frame").subscribe(onNext: { (frame : CGRect?) in            
            print(frame!)            
        }).addDisposableTo(bag)

四 RxSwift常见操作

4-1 never的obserable
// 创建一个naver的obserable 从来不执行
        let neverO = Observable<String>.never()
        neverO.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)
        
4-2 empty的Obserable 只发出complete事件
        // 创建一个empty的Obserable 只能发出一个complete事件
        let empty = Observable<String>.empty()
        empty.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)

4-3 just

// just是创建一个sequence只能发出一种特定的事件 能正常结束
        let just = Observable.just("10")
        just.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)

4-4 of
//创建一个sequence 能发出很多事件信号
        let of = Observable.of("a","b","c")
        of.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)
4-5 from
 // from就是从数组中创建sequence
        let from = Observable.from(["1","2","3"])
        from.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)

4-6 create 自定义事件 开发中常用
//  create 创建一个自定义的disposable  实际开发中常用的  会在自定义很多事件来监听的

        let create = createObserable()
        create.subscribe { (event : Event<Any>) in
            print(event)
        }.addDisposableTo(bag)

// 方法
    func createObserable() -> Observable<Any> {        
        return Observable.create({ (observer : AnyObserver<Any>) -> Disposable in            
            observer.onNext("奥卡姆剃须刀")
            observer.onNext("18")
            observer.onNext("65")
            observer.onCompleted()
            
            return Disposables.create()
        })
    }


// 自定义just
let myJust = myJustObservable(element: "奥卡姆剃须刀")        
        myJust.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)


// 方法
    func myJustObservable(element:String) -> Observable<String> {        
        return Observable.create({ (observer : AnyObserver<String>) -> Disposable in            
            observer.onNext(element)            
            observer.onCompleted()            
            return Disposables.create()            
        })
    }


4-7 range 这个作用不是很大

        let range = Observable.range(start: 1, count: 10)
        range.subscribe { (event : Event<Int>) in
            print(event)
        }.addDisposableTo(bag)

4-8 repeat

        let repeatLL = Observable.repeatElement("奥卡姆剃须刀")
        // 重复次数
        repeatLL.take(5).subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)

五 RxSwift中的Subjects

5-1 Subjects 是什么?

Subjects 是Observable 和 Observer 之间的桥梁, 一个subject 既是一个Obserable 也是一个 Observer 他既可以发出事件,也可以监听事件

5-2 PublishSubject

当你订阅PublishSubject的时候,你只能接受订阅他之后发生的事件,subject.onNext() 发出onNext事件,对应的还有onError() 和onCompleted() 事件

        // 1 publishSubject 订阅者只能接受,订阅之后的事件 也就是必须先订阅 再发送事件
        let publishSub = PublishSubject<String>()        
        publishSub.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)        
        publishSub.onNext("奥卡姆剃须刀")
5-3 ReplySubject

ReplySubject 当你订阅ReplySubject 的时候,你可以接收到订阅他之后的事件,但也可以接收订阅他之前发出的事件 ,接收几个事件取决于bufferSize的大小 会接收最后发送的信号

     
// 限制两个信号         
//      let replySub  = ReplaySubject<String>.create(bufferSize: 2)
        // 没有限制的replySubject
        let replySub = ReplaySubject<String>.createUnbounded()
        
        replySub.onNext("1")
        replySub.onNext("2")
        replySub.onNext("3")
        replySub.onNext("4")
        
        replySub.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)
        
        replySub.onNext("5")

5-4 BehaviorSubject

当你订阅了BehaviorSubject 你就会接收到订阅之前的最后一个事件 可以初始化的时候就给一个订阅值
这个用的是最多的 一般用法是初始的时候给一个默认数据 然后进行刷新加载更多数据

        let behaviorSub = BehaviorSubject(value: "10")        
        behaviorSub.onNext("a")
        // 只能订阅到 b
        behaviorSub.onNext("b")        
        behaviorSub.subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)        
        behaviorSub.onNext("11")
        behaviorSub.onNext("12")
        behaviorSub.onNext("13")

5-5 Variable

1 Variable 是BehaviorSubject 一个包装箱 就像是一个箱子一样 使用的时候需要调用asObservable() 拆箱,里面的Value 是一个BehaviorSubject
2 如果 Variable 打算发出事件 直接修改对象的Value即可
3 当事件结束的时候 Variable 会自动发出complete事件

        let variable = Variable("a")        
        // 要是想修改值 直接修改value就好
        variable.value = "b"        
        variable.asObservable().subscribe { (event : Event<String>) in
            print(event)
        }.addDisposableTo(bag)        
        // 也能发出事件
        variable.value = "c"
        variable.value = "d"

六 RxSwift中的变换操作

6-1 map

通过传入一个函数闭包把原来的sequence转变为一个新的sequence的操作


    //  1 swift中map的使用
        let array = [1,2,3,4]
        
        let arr2 = array.map { (num : Int) -> Int in
            return num * num
        }
        
        print(arr2)
  //    2  swift的函数式编程  用的还是比较少的 还是习惯于面向对象的方式
        let arr3 = array.map({ $0 * $0 })
        
        print(arr3)
        
 //    3 rxswift 中map函数的使用
        Observable.of(10,11,12,13)
            .map { (num : Int) -> Int in
                return num * num
            }.subscribe { (event : Event<Int>) in
                print(event)
            }.addDisposableTo(bag)

6-2 flatmap

将一个sequence转换成sequences。 当你接受一个sequence事件,你还想接受其他sequence发出的事件的话 可以使用flatmap,他会将每一个sequence事件进行处理后 然后再以一个sequence形式发出事件

// 1  先定义一个结构体

// RxSwift的思想  让任何一个变量都是可以监听的
struct Student {
    var score : Variable<Double>    
}


        // 3 flatmap 的使用  映射 Observable的
        let stu1 = Student(score: Variable(100))
        let stu2 = Student(score: Variable(99))
        let stu3 = Student(score: Variable(98))
        
        
        //   链式编程思维
        let studentVariable = Variable(stu1)
        //  这个方法会把所有的是都监听到 都打印 但常常我们只关心最新的一个订阅
//        studentVariable.asObservable().flatMap { (stu : Student) -> Observable<Double> in
//            return stu.score.asObservable()
//            }.subscribe { (event : Event<Double>) in
//            print(event)
//        }.addDisposableTo(bag)
        
        // 常用的是这一个方法  会先打印一下初始化的数据  只会关心最新订阅值的改变
        studentVariable.asObservable().flatMapLatest { (stu : Student) -> Observable<Double> in
            return stu.score.asObservable()
            }.subscribe { (event : Event<Double>) in
                print(event)
            }.addDisposableTo(bag)
        
        studentVariable.value = stu2
        stu2.score.value = 0
        // 这样的话每一个值的改变都会发送信号
        
        //  我已经不关心你的值的改变 我只关心最新的订阅的值的变化
        stu1.score.value = 1000;

七 资源的释放

  • 当监听一个事件序列的时候,有消息事件来了,我们做某些事情,但是这个事件序列不在发出消息了,我们的监听也就没有什么存在价值了,所以我们需要释放我们这些监听资源,其实也就是每种编程语言中的内存资源释放,
  • OC 和Swift 也一样,在你不需要某些变量的时候,你需要吧这些变量所占用的内存空间释放掉,
  • 释放某一个监听的时候,我们可以手动调用释放方法
7-1 dispose
  • 相当于MRC中手动调用release操作

  • 注意:因为观察者已经销毁,所以后面无法接受事件

      // 1  dispose() 让对象立即销毁掉 后边在改变值的时候 此对象已经销毁了
      let variable1 = Variable("奥卡姆剃须刀")
      variable1.asObservable().subscribe { (event : Event<String>) in
          print(event)
      }.dispose()
    
7-2 Dispose Bags
  • 除了上边手动的方法 还有一种自动的方式 推荐使用这种方式 这种方式就好像iOS中的ARC方式 会自动去释放资源
    // 2 DisposeBag
    fileprivate lazy var bag : DisposeBag = DisposeBag()

    let subject = BehaviorSubject(value: "a")
    subject.subscribe { (event : Event<String>) in
        print(event)
    }.addDisposableTo(bag)

八 RxSwift下的UITableView的使用


// VC 中的代码

        //1.创建UITableView(跟OC几乎一样)
        let tabV = UITableView(frame: view.bounds, style: UITableViewStyle.plain)
        tableView = tabV
        
        
        //2.注册Cell
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
        
        self.view.addSubview(tableView)
        
        //  负责数据绑定  传回来row  model  和 cell  自行复制
        viewModel.modelObserable.asObservable()
            .bind(to: tableView.rx.items(cellIdentifier: cellID,
                 cellType: UITableViewCell.self)){ row, model, cell in
                 cell.textLabel?.text = model.name
        }.addDisposableTo(bag)                

        // 监听点击cell 获取index
        tabV.rx.itemSelected.subscribe(onNext: { (index : IndexPath) in            
//            点击cell就刷新数据
//            self.reloadData()            
        }).addDisposableTo(bag)        

        // 监听点击cell 获取Model
        tabV.rx.modelSelected(RxModel.self).subscribe(onNext: { (model : RxModel) in            
            print(model.name)            
        }).addDisposableTo(bag)

VIewModel中的代码
var modelObserable : Variable<[RxModel]> = {        
        var models : [RxModel] = [RxModel]()        
        for i in 0..<20 {            
            let model = RxModel()
            model.name = "我是小\(i)"
            models.append(model)
        }        
        return Variable(models)        
    }()

本文代码Demo

《多次更新完结》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容