RxSwift详解(1)

最近开始看RxSwift ,将自己的学习过程记录下来。

ReactiveCocoa 中,所有的数据都是以signal流的形式传递,其实在Rx中也是如此,本质并没有改变,改变的是形式。ReactiveCocoa 中的signal 对应Rx 的Observable

  • 创建信号
  • 常见方法的使用

常见方法的使用

RxCocoa 中的UI类

number: UITextField! 无需通过添加任何操作,只要subscribeNext 操作就会执行打印输出

number1.rx_text.subscribeNext{ (text) -> Void in
            print(" --- text \(text)");
            }
combinLatest(...)

将多个信号整合成一个信号,任何一个信号的改变均会触发操作

Observable.combineLatest(number1.rx_text, number2.rx_text, number3.rx_text) { textValue1, textValue2, textValue3 -> Int in
                return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
            }
            .map {
                print("value = \($0)");
                return $0.description // $0 代表第一个参数
            
            }
            .bindTo(result.rx_text)
            .addDisposableTo(disposeBag)
map

信号映射转换。例如 将一个String 转换为 Int

bindTo

值绑定,将一个信号与另外一个信号绑定

常见方法

create
 func createSequence(){
        
        let myCreate = { (element: Int) -> Observable<Int> in
            return Observable.create { observer in
                observer.on(.Next(element))
                observer.on(.Completed)
                return NopDisposable.instance
            }
        }
        let subscription5 = myCreate(1).subscribe { event in
            print(event)
            /*
            Next(1)
            Completed
            */
        }
    }
of
func ofSequence(){
        let sequenceElements = Observable.of(1, 2, 3, 4)
        let _ = sequenceElements.subscribe { event in
            print(event)
        }
        /*
        Next(1)
        Next(2)
        Next(3)
        Next(4)
        Completed
        */    
    }
deferred
 func deferSquence(){
        let deferredSequence: Observable<Int> = Observable.deferred {
            print("creating")
            return Observable.create { observer in
                print("emmiting")
                observer.on(.Next(0))
                observer.on(.Next(1))
                observer.on(.Next(2))
                
                return NopDisposable.instance
            }
        }
        
        _ = deferredSequence
            .subscribe { event in
                print(event)
        }
        
        _ = deferredSequence
            .subscribe { event in
                print(event)
        }
    }

Subject 既可以作为Observer, 也可以作为Observable,作为observer,可以订阅一个或者多个observables,作为observable,可以传递其观察的item

PublishSubject

只有在subscribe之后才会接收输出结果,如果subscribe之后没有数据的发送,则也不会有输出。这里的on 如同ReactiveCocoa 的Signal.sendNext()方法

func publishSubject(){
        
        //let disposeBag = DisposeBag()
        
        let subject = PublishSubject<String>()
         subject.on(.Next("0"))
        subject.subscribe { event in
            print("1->\(event)")
        }
       
        subject.on(.Next("a"))
        subject.on(.Next("b"))
        subject.subscribe { event in
            print("2->\(event)")
        }
        subject.subscribeNext { (vc) -> Void in
            print("3->\(vc)")
        }
        subject.on(.Next("c"))
        subject.on(.Next("d"))
        
        subject.addDisposableTo(DisposeBag());
        /*
        不会缓存数据
        1->Next(a)
        1->Next(b)
        
        1->Next(c)
        2->Next(c)
        3 c
        
        1->Next(d)
        2->Next(d)
        3 d
        */
}
publishsubject.png
replaySubject

每次subscribe 之后会先输出缓冲的数据,可以先发送数据然后再subscribe。(这与ReactiveCocoa 的replaySubject 原理应该是一样的,都是有数据缓冲池,所有发送过的数据都不会消失)。 可以设置缓冲大小。

  func replaySubject(){
        let disposeBag = DisposeBag()
        // 会缓存数据
        let subject = ReplaySubject<String>.create(bufferSize: 1)// 设置缓冲的大小
        subject.on(.Next("0"))
        subject.subscribeNext { (vc) -> Void in
            print("1->\(vc)")
        }
       
        subject.on(.Next("a"))
        subject.on(.Next("b"))
        subject.subscribeNext { (vc) -> Void in
            print("2->\(vc)")// 当subscribeNext 后,会先输出缓冲的数据
        }
        subject.on(.Next("c"))
        subject.on(.Next("d"))
        subject.addDisposableTo(disposeBag);
        /*
        1->0
        1->a
        1->b
        
        2->b // 缓冲为1 所以输出最新的一个
        
        1->c
        2->c
        
        1->d
        2->d
        */
        
    }
replaysubject.png
BehaviorSubject

When an observer subscribes to a BehaviorSubject, it begins by emitting the item most recently emitted by the source Observable (or a seed/default value if none has yet been emitted) and then continues to emit any other items emitted later by the source Observable(s).

 func behavirSubject(){
        let subject = BehaviorSubject(value: "z")
        subject.on(.Next("0"))
        subject.on(.Next("1"))
        subject.subscribe { event in
            print("1->\(event)")
        }
        subject.on(.Next("a"))
        subject.on(.Next("b"))
        subject.subscribe { event in
            print("2->\(event)")
        }
        subject.on(.Next("c"))
        subject.on(.Completed)
        
        /*
        1->Next(z)// 如果没有默认值 则使用初始化的默认值,如果已经在subscribe 之前设置,则使用最新的
        1->Next(a)
        1->Next(b)
        2->Next(b)
        1->Next(c)
        2->Next(c)
        1->Completed
        2->Completed
        
        */
    }
behaviorsubject.png
Variable

Variable wraps BehaviorSubject. Advantage of using variable over BehaviorSubject is that variable can never explicitly complete or error out, and BehaviorSubject can in case Error or Completed message is send to it. Variable will also automatically complete in case it's being deallocated.

func varibaleSequence(){
        let disposeBag = DisposeBag()
        let variable = Variable("z")
        variable.asObservable().subscribeNext { (vc) -> Void in
            print("1->\(vc) ")
        }
      //  writeSequenceToConsole("1", sequence: variable.asObservable()).addDisposableTo(disposeBag)
        variable.value = "a"
        variable.value = "b"
        variable.asObservable().subscribeNext { (vc) -> Void in
            print("2->\(vc) ")
        }
       // writeSequenceToConsole("2", sequence: variable.asObservable()).addDisposableTo(disposeBag)
        variable.value = "c"
        variable.value = "d"
        
    /*
    Varibale 是BehaviorSubject 的包装器,较于BehaviorSubject 不会显示输出 complete 或 error
        Variable 在释放后会自动 complete
        1->z
        
        1->a
        1->b
        
        2->b
        
        1->c 
        2->c 
        
        1->d 
        2->d
        */
    }

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

推荐阅读更多精彩内容