亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ReactiveCocoa比較區分replay,replayLast和replayLazily

2019-11-14 18:15:53
字體:
來源:轉載
供稿:網友

    一直搞不明白replayLazily可以直接跳到最后看。

   原文:http://spin.atomicobject.com/2014/06/29/replay-replaylast-replaylazily/

  最近同事問我在ReactiveCoca中replay,replayLast和replayLazily有什么區別,但我對此也是一知半解,也不能完整描述出來它們之間的不同,所以,我將對它們進行深入研究。

  如果你沒有對RACReplaySubject和RACMulticastConnection有很好的理解的話,你會對它們在頭文件中的描述理解的很困難?,F在不去了解底層原理,我會嘗試去描述解析這些方法。

Subscribing to a Signal

  對于一個“普通”的信號,每次訂閱都將會導致信號中的代碼再執行一遍,且該次訂閱者僅接收到該次訂閱發送出去的值。

  第一個例子演示每次訂閱都會重新執行訂閱代碼。

__block int num = 0;  RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id  subscriber) {      num++;      NSLog(@"Increment num to: %i", num);      [subscriber sendNext:@(num)];      return nil;  }];   NSLog(@"Start subscriptions");   // Subscriber 1 (S1)  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   // Subscriber 2 (S2)  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   // Subscriber 3 (S3)  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];

  運行結果如下:

Start subscriptions  Increment num to: 1  S1: 1  Increment num to: 2  S2: 2  Increment num to: 3  S3: 3

  可以看到,每次訂閱num都在遞增,如果不訂閱則不會遞增。通過這種方式,可以知道信號是懶惰的,如果沒有訂閱者的話,是不會執行的。

  第二個例子演示信號被添加訂閱的時候,訂閱者是怎么接收發送的值的。

 RACSubject *letters = [RACSubject subject];  RACSignal *signal = letters;   NSLog(@"Subscribe S1");  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   NSLog(@"Send A");  [letters sendNext:@"A"];  NSLog(@"Send B");  [letters sendNext:@"B"];   NSLog(@"Subscribe S2");   [signal subscribeNext:^(id x) {       NSLog(@"S2: %@", x);  }];   NSLog(@"Send C");  [letters sendNext:@"C"];  NSLog(@"Send D");  [letters sendNext:@"D"];   NSLog(@"Subscribe S3");  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];

運行結果

Subscribe S1 Send AS1: A Send BS1: B Subscribe S2 Send CS1: CS2: C Send DS1: DS2: D Subscribe S3

  在很多情況下,這是我們想要的預期結果,不過在某些情況下,你不需要訂閱的代碼再次被執行。例如訂閱 一個向網絡服務器發送的請求,當服務器返回數據時,多個監聽者需要更新(無論有多少個監聽者,請求只發送一下(第一個例子就不滿足我們的需求)),或者我們想拿到訂閱前信號發送過的值(第二個例子,S2想拿A,B的值或者S3想拿A,B,C,D的值,就不滿足我們的需求了)。因此-replay-replayLast, and -replayLazily應需而生。

Subscribing to a -replay Signal

  這個replay方法將返回一個新的信號,當源信號被訂閱時,會立即發送給訂閱者全部歷史的值,不會重復執行源信號中的訂閱代碼,不僅如此,訂閱者還將收到所有未來發送過去的值。

  第一個例子演示信號添加新的訂閱時,代碼是不會再次被執行的。

__block int num = 0;  RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id  subscriber) {      num++;      NSLog(@"Increment num to: %i", num);      [subscriber sendNext:@(num)];      return nil;  }] replay];   NSLog(@"Start subscriptions");   // Subscriber 1 (S1)  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   // Subscriber 2 (S2)  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   // Subscriber 3 (S3)  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];
Increment num to: 1  Start subscriptions  S1: 1  S2: 1  S3: 1

  信號首次被訂閱時,num立馬被遞增了,且僅僅遞增了一次。這說明了不管有你多個訂閱者,訂閱代碼我只執行了一次。

  

  第二個例子演示每個新添加的訂閱者接收到信號中全部的值(不管是之前發出的值還是將來發出的值)。

  

RACSubject *letters = [RACSubject subject];  RACSignal *signal = [letters replay];   NSLog(@"Subscribe S1");  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   NSLog(@"Send A");  [letters sendNext:@"A"];  NSLog(@"Send B");  [letters sendNext:@"B"];   NSLog(@"Subscribe S2");  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   NSLog(@"Send C");  [letters sendNext:@"C"];  NSLog(@"Send D");  [letters sendNext:@"D"];   NSLog(@"Subscribe S3");  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];
Subscribe S1    Send A   S1: A Send BS1: B Subscribe S2S2: AS2: B Send CS1: CS2: C Send DS1: DS2: D Subscribe S3S3: AS3: BS3: CS3: D

  盡管訂閱者S3在所有的值發送之后再訂閱,然后還能接收到所有的值。

Subscribing to a -replayLast Signal

  這個replayLast返回一個新的信號,當源信號被訂閱時,會立即發送給訂閱者最新的值,不會重復執行源信號中的訂閱代碼。訂閱者還會收到信號未來所有的值。

  對于第一個例子,跟之前replay一樣,所以我就不再次演示了。

  第二個例子演示如何將最新的值提供給新的訂閱者

RACSubject *letters = [RACSubject subject];  RACSignal *signal = [letters replayLast];   NSLog(@"Subscribe S1");  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   NSLog(@"Send A");  [letters sendNext:@"A"];  NSLog(@"Send B");  [letters sendNext:@"B"];   NSLog(@"Subscribe S2");  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   NSLog(@"Send C");  [letters sendNext:@"C"];  NSLog(@"Send D");  [letters sendNext:@"D"];   NSLog(@"Subscribe S3");  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];
Subscribe S1 Send AS1: A Send BS1: B Subscribe S2S2: B Send CS1: CS2: C Send DS1: DS2: D Subscribe S3S3: D

Subscribing to a -replayLazily Signal

  這replayLazily方法返回一個新的信號,當源信號被訂閱時,會立即發送給訂閱者全部歷史的值,不會重復執行源信號中的訂閱代碼。跟replay不同的是,replayLazily被訂閱生成新的信號之前是不會對源信號進行訂閱的(原文寫的有點繞,簡單來講 直到訂閱時候才真正創建一個信號,源信號的訂閱代碼才開始執行)。暫時不理解也沒事,看下面的代碼輸出,和注釋。

 這第一個例子會說明跟replay差異。 注意字符串 “Increment num to: 1”是被訂閱了之后才打印顯示的。而replay和replayLast沒被訂閱前就打印了“Increment num to: 1” 這個消息。

__block int num = 0;  RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id  subscriber) {      num++;      NSLog(@"Increment num to: %i", num);      [subscriber sendNext:@(num)];      return nil;  }] replayLazily];  //跟replay不同的就這么一個地方   NSLog(@"Start subscriptions");   // Subscriber 1 (S1)  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   // Subscriber 2 (S2)  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   // Subscriber 3 (S3)  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];
// 帖子滾動起來,跟replay比較一下 Increment num to: 1 的顯示順序。Start subscriptions     // 實際訂閱Increment num to: 1 // 信號開始創建S1: 1S2: 1S3: 1

 

  第二個例子演示將全部歷史的值提供給任何新的訂閱者,就像replay一樣。

RACSubject *letters = [RACSubject subject];  RACSignal *signal = [letters replayLazily];   NSLog(@"Subscribe S1");  [signal subscribeNext:^(id x) {      NSLog(@"S1: %@", x);  }];   NSLog(@"Send A");  [letters sendNext:@"A"];  NSLog(@"Send B");  [letters sendNext:@"B"];   NSLog(@"Subscribe S2");  [signal subscribeNext:^(id x) {      NSLog(@"S2: %@", x);  }];   NSLog(@"Send C");  [letters sendNext:@"C"];  NSLog(@"Send D");  [letters sendNext:@"D"];   NSLog(@"Subscribe S3");  [signal subscribeNext:^(id x) {      NSLog(@"S3: %@", x);  }];
Subscribe S1 Send AS1: A Send BS1: B Subscribe S2S2: AS2: B Send CS1: CS2: C Send DS1: DS2: D Subscribe S3S3: AS3: BS3: CS3: D

  總結一下:

  ReactiveCocoa提供了這三個簡便的方法允許多個訂閱者訂閱一個信號,卻不會重復執行訂閱代碼,并且能給新加的訂閱者提供訂閱前的值。replay和replayLast使信號變成熱信號,且會提供所有值(-replay) 或者最新的值(-replayLast) 給訂閱者。 replayLazily返回一個冷的信號,會提供所有的值給訂閱者。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
免费99精品国产自在在线| 亚洲一二在线观看| 日韩精品中文字幕有码专区| 久久在线精品视频| 欧美色视频日本高清在线观看| 久久亚洲精品小早川怜子66| 日韩av在线免费| 北条麻妃一区二区在线观看| 国产91精品最新在线播放| 亚洲色图校园春色| 色噜噜狠狠色综合网图区| 欧美视频在线观看 亚洲欧| 色偷偷888欧美精品久久久| 欧美亚洲免费电影| 久久久亚洲福利精品午夜| 欧美最猛性xxxxx免费| 精品国产一区二区三区久久狼5月| 国产精品久久久久久久午夜| 亚洲精品v天堂中文字幕| 久久久久久久久久亚洲| 中文字幕精品www乱入免费视频| 久久久av一区| 精品中文字幕乱| 欧美成人精品在线视频| 日韩成人在线免费观看| 欧美精品videossex88| 久久夜色精品国产| 亚洲视频在线观看视频| 日韩电影中文字幕av| 亚洲第一福利视频| 精品伊人久久97| 欧洲美女7788成人免费视频| 中国china体内裑精亚洲片| 久久韩剧网电视剧| 久久久91精品国产一区不卡| 国产精品在线看| 亚洲男人的天堂在线| 国产欧美日韩精品专区| 久久精品国亚洲| 国产亚洲美女久久| 欧美精品在线免费观看| 日韩精品免费电影| 欧美成人免费一级人片100| 亚洲国产精久久久久久| 久久91精品国产91久久跳| 亚洲free嫩bbb| 成年无码av片在线| 国产亚洲成精品久久| 国产精品白嫩美女在线观看| 久久久免费精品视频| 亚洲2020天天堂在线观看| 日韩欧美在线中文字幕| 午夜精品一区二区三区在线视频| 欧美大成色www永久网站婷| 91久久嫩草影院一区二区| 久久天天躁狠狠躁夜夜av| 亚洲美女又黄又爽在线观看| 亚洲精品久久视频| 国产亚洲欧洲高清一区| 国产一区二区三区三区在线观看| 在线播放日韩av| 成人午夜在线影院| 亚洲综合在线播放| 欧美在线视频一区二区| 久久亚洲国产精品| 欧美性高潮在线| 最近2019免费中文字幕视频三| 超碰97人人做人人爱少妇| 欧美大片在线免费观看| 日本电影亚洲天堂| 欧美丰满老妇厨房牲生活| 欧美日韩亚洲视频| 精品夜色国产国偷在线| 综合激情国产一区| 91欧美激情另类亚洲| 欧美xxxwww| 中文字幕不卡av| 久久成人一区二区| 国产a级全部精品| 欧美成人黄色小视频| 国模吧一区二区| 欧美日韩精品在线观看| 91香蕉亚洲精品| 在线日韩日本国产亚洲| 国产视频久久久久| 韩国三级电影久久久久久| 91精品久久久久久久久久久| 亚洲精品欧美日韩专区| 亚洲四色影视在线观看| 国产成人欧美在线观看| 国产精品美女久久久久av超清| 精品国产户外野外| 久久伊人免费视频| 亚洲无线码在线一区观看| 亚洲国产天堂久久综合| 精品国产鲁一鲁一区二区张丽| 久久视频在线免费观看| 亚洲精品自拍偷拍| 中文字幕日韩在线播放| 久久久久久这里只有精品| www.日韩欧美| 国产成人av网址| 国产精品狼人色视频一区| 久久国产精品久久久久久久久久| 91精品国产成人| 97超级碰在线看视频免费在线看| 亚洲一区二区久久久久久久| 在线午夜精品自拍| 97久久国产精品| 国产在线观看91精品一区| 亚洲二区中文字幕| 欧美日韩性生活视频| 日韩av在线播放资源| 91亚洲人电影| 国产精品免费视频xxxx| 国产精品一香蕉国产线看观看| 亚洲国产精品久久久久秋霞不卡| 国外日韩电影在线观看| 欧美激情视频免费观看| 久久在线观看视频| 中文字幕日韩欧美精品在线观看| 欧美超级免费视 在线| 久久人人爽人人爽人人片亚洲| 成人国产精品久久久久久亚洲| 欧美小视频在线| 在线亚洲男人天堂| 91在线免费网站| 丝袜亚洲另类欧美重口| 国产亚洲欧美一区| 欧美性xxxxx| 欧美成人午夜激情视频| 国产+成+人+亚洲欧洲| 综合网日日天干夜夜久久| 夜夜嗨av一区二区三区免费区| 欧美老女人bb| 欧美特黄级在线| 国产69精品久久久久久| 亚洲国产日韩精品在线| 国内免费久久久久久久久久久| 韩剧1988免费观看全集| 亚洲天堂久久av| 国产精品久久久久aaaa九色| 国产一级揄自揄精品视频| 国产午夜精品全部视频播放| 综合欧美国产视频二区| 国产极品精品在线观看| 日韩电影免费在线观看中文字幕| 久久国产精品久久久久久久久久| 992tv成人免费视频| 中文字幕免费精品一区高清| 久久av中文字幕| 国产精品欧美激情在线播放| 国产亚洲日本欧美韩国| 亚洲第一天堂无码专区| 欧美午夜性色大片在线观看| 亚洲欧洲中文天堂| 91九色精品视频| 91av中文字幕| 红桃视频成人在线观看| 日本中文字幕不卡免费| 亚洲91精品在线| 欧美电影免费看| 欧美精品福利视频| 欧美极品少妇xxxxⅹ裸体艺术|