RAC(Reactive Cocoa)常見的類

ReactiveCocoa常見的類

RACSignal:信號(hào)類;RACSubscriber是協(xié)議

簡(jiǎn)介

有數(shù)據(jù)產(chǎn)生時(shí)就會(huì)使用RACSignal類

默認(rèn)是冷信號(hào),必須訂閱信號(hào)類

RACSignal使用步驟

創(chuàng)建信號(hào)(默認(rèn)創(chuàng)建的是冷信號(hào))

didSubscribe調(diào)用:只要一個(gè)信號(hào)被訂閱就會(huì)調(diào)用

didSubscribe作用:發(fā)送數(shù)據(jù)

訂閱信號(hào)(變?yōu)闊嵝盘?hào))subscribeNext:訂閱

nextBlock調(diào)用:只要訂閱者發(fā)送數(shù)據(jù)就會(huì)調(diào)用

nextBlock作用:處理數(shù)據(jù),展示在UI上面

發(fā)送信號(hào)(sendNext:)

只要訂閱者調(diào)用sendNext就會(huì)執(zhí)行nextBlock

只要訂閱RACDynamicSignal就會(huì)執(zhí)行didSubscribe

前提條件是RACDynamicSignal,不同類型信號(hào)的訂閱,處理訂閱的事情不一樣

RACSignal使用步驟:

1.創(chuàng)建信號(hào) + (RACSignal *)createSignal:(RACDisposable * (^)(id subscriber))didSubscribe

2.訂閱信號(hào),才會(huì)激活信號(hào). - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

3.發(fā)送信號(hào) - (void)sendNext:(id)value

RACSignal底層實(shí)現(xiàn):

1.創(chuàng)建信號(hào)跳昼,首先把didSubscribe保存到信號(hào)中秀姐,還不會(huì)觸發(fā)理澎。

2.當(dāng)信號(hào)被訂閱,也就是調(diào)用signal的subscribeNext:nextBlock

2.2 subscribeNext內(nèi)部會(huì)創(chuàng)建訂閱者subscriber正歼,并且把nextBlock保存到subscriber中。

2.1 subscribeNext內(nèi)部會(huì)調(diào)用siganl的didSubscribe

3.siganl的didSubscribe中調(diào)用[subscriber sendNext:@1];

3.1 sendNext底層其實(shí)就是執(zhí)行subscriber的nextBlock

// 1.創(chuàng)建信號(hào)

RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id subscriber) {

// block調(diào)用時(shí)刻:每當(dāng)有訂閱者訂閱信號(hào),就會(huì)調(diào)用block转砖。

// 2.發(fā)送信號(hào)

[subscriber sendNext:@1];

// 如果不在發(fā)送數(shù)據(jù),最好發(fā)送信號(hào)完成鲸伴,內(nèi)部會(huì)自動(dòng)調(diào)用[RACDisposable disposable]取消訂閱信號(hào)府蔗。

[subscriber sendCompleted];

return [RACDisposable disposableWithBlock:^{

// block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)送完成或者發(fā)送錯(cuò)誤,就會(huì)自動(dòng)執(zhí)行這個(gè)block,取消訂閱信號(hào)汞窗。

// 執(zhí)行完Block后姓赤,當(dāng)前信號(hào)就不在被訂閱了。

NSLog(@"信號(hào)被銷毀");

}];

}];

// 3.訂閱信號(hào),才會(huì)激活信號(hào).

[siganl subscribeNext:^(id x) {

// block調(diào)用時(shí)刻:每當(dāng)有信號(hào)發(fā)出數(shù)據(jù)仲吏,就會(huì)調(diào)用block.

NSLog(@"接收到數(shù)據(jù):%@",x);

}];

2.? RACDisposable:取消訂閱

只要信號(hào)發(fā)送數(shù)據(jù)完畢就會(huì)自動(dòng)取消訂閱

只要訂閱者在就不會(huì)自動(dòng)取消信號(hào)的訂閱

調(diào)用[disposable dispose];就會(huì)取消

3.? RACSubject:信號(hào)提供者,自己可以充當(dāng)信號(hào),也可以充當(dāng)訂閱者

必須先訂閱再發(fā)送信號(hào)

使用場(chǎng)景: 通常用來代替代理,有了他就不必定義代理了

RACSubject使用步驟

1.創(chuàng)建信號(hào) [RACSubject subject]不铆,跟RACSiganl不一樣,創(chuàng)建信號(hào)時(shí)沒有block裹唆。

2.訂閱信號(hào) - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

3.發(fā)送信號(hào) sendNext:(id)value

RACSubject:底層實(shí)現(xiàn)和RACSignal不一樣狂男。

1.調(diào)用subscribeNext訂閱信號(hào),只是把訂閱者保存起來品腹,并且訂閱者的nextBlock已經(jīng)賦值了岖食。

2.調(diào)用sendNext發(fā)送信號(hào),遍歷剛剛保存的所有訂閱者舞吭,一個(gè)一個(gè)調(diào)用訂閱者的nextBlock泡垃。

// 1.創(chuàng)建信號(hào)

RACSubject *subject = [RACSubject subject];

// 2.訂閱信號(hào)

[subject subscribeNext:^(id x) {

// block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)出新值析珊,就會(huì)調(diào)用.

NSLog(@"第一個(gè)訂閱者%@",x);

}];

[subject subscribeNext:^(id x) {

// block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)出新值,就會(huì)調(diào)用.

NSLog(@"第二個(gè)訂閱者%@",x);

}];

// 3.發(fā)送信號(hào)

[subject sendNext:@"1"];

4.? RACReplaySubject: 重復(fù)提供信號(hào)類,是RACSubject的子類

RACReplaySubject可以先發(fā)送信號(hào)蔑穴,在訂閱信號(hào)忠寻,RACSubject就不可以。

使用場(chǎng)景一`:如果一個(gè)信號(hào)每被訂閱一次存和,就需要把之前的值重復(fù)發(fā)送一遍奕剃,使用重復(fù)提供信號(hào)類。

使用場(chǎng)景二`:可以設(shè)置capacity數(shù)量來限制緩存的value的數(shù)量,即只緩充最新的幾個(gè)值捐腿。

RACReplaySubject使用步驟:

1.創(chuàng)建信號(hào) [RACSubject subject]纵朋,跟RACSiganl不一樣,創(chuàng)建信號(hào)時(shí)沒有block茄袖。

2.可以先訂閱信號(hào)操软,也可以先發(fā)送信號(hào)。

2.1 訂閱信號(hào) - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock

2.2 發(fā)送信號(hào) sendNext:(id)value

RACReplaySubject:底層實(shí)現(xiàn)和RACSubject不一樣宪祥。

1.調(diào)用sendNext發(fā)送信號(hào)聂薪,把值保存起來,然后遍歷剛剛保存的所有訂閱者蝗羊,一個(gè)一個(gè)調(diào)用訂閱者的nextBlock藏澳。

2.調(diào)用subscribeNext訂閱信號(hào),遍歷保存的所有值耀找,一個(gè)一個(gè)調(diào)用訂閱者的nextBlock

如果想當(dāng)一個(gè)信號(hào)被訂閱笆载,就重復(fù)播放之前所有值,需要先發(fā)送信號(hào)涯呻,在訂閱信號(hào)凉驻。也就是先保存值,在訂閱值复罐。

// 1.創(chuàng)建信號(hào)

RACReplaySubject *replaySubject = [RACReplaySubject subject];

// 2.發(fā)送信號(hào)

[replaySubject sendNext:@1];

[replaySubject sendNext:@2];

// 3.訂閱信號(hào)

[replaySubject subscribeNext:^(id x) {

NSLog(@"第一個(gè)訂閱者接收到的數(shù)據(jù)%@",x);

}];

// 訂閱信號(hào)

[replaySubject subscribeNext:^(id x) {

NSLog(@"第二個(gè)訂閱者接收到的數(shù)據(jù)%@",x);

}];

>>> RACSubject替換代理

需求:

1.給當(dāng)前控制器添加一個(gè)按鈕涝登,modal到另一個(gè)控制器界面

2.另一個(gè)控制器view中有個(gè)按鈕,點(diǎn)擊按鈕效诅,通知當(dāng)前控制器

步驟一:在第二個(gè)控制器.h胀滚,添加一個(gè)RACSubject代替代理。

@interface TwoViewController : UIViewController

@property (nonatomic, strong) RACSubject *delegateSignal;

@end

步驟二:監(jiān)聽第二個(gè)控制器按鈕點(diǎn)擊

@implementation TwoViewController

- (IBAction)notice:(id)sender {

// 通知第一個(gè)控制器乱投,告訴它咽笼,按鈕被點(diǎn)了

// 通知代理

// 判斷代理信號(hào)是否有值

if (self.delegateSignal) {

// 有值,才需要通知

[self.delegateSignal sendNext:nil];

}

}

@end

步驟三:在第一個(gè)控制器中戚炫,監(jiān)聽跳轉(zhuǎn)按鈕剑刑,給第二個(gè)控制器的代理信號(hào)賦值,并且監(jiān)聽.

@implementation OneViewController

- (IBAction)btnClick:(id)sender {

// 創(chuàng)建第二個(gè)控制器

TwoViewController *twoVc = [[TwoViewController alloc] init];

// 設(shè)置代理信號(hào)

twoVc.delegateSignal = [RACSubject subject];

// 訂閱代理信號(hào)

[twoVc.delegateSignal subscribeNext:^(id x) {

NSLog(@"點(diǎn)擊了通知按鈕");

}];

// 跳轉(zhuǎn)到第二個(gè)控制器

[self presentViewController:twoVc animated:YES completion:nil];

}

@end

5.? RACTuple: 元組類

RACSequence:集合類,用于代替NSArray,NSDictionary,可以用來快速遍歷數(shù)組和字典

// 1.遍歷數(shù)組

NSArray *numbers = @[@1,@2,@3,@4];

// 這里其實(shí)是三步

// 第一步: 把數(shù)組轉(zhuǎn)換成集合RACSequence numbers.rac_sequence

// 第二步: 把集合RACSequence轉(zhuǎn)換RACSignal信號(hào)類,numbers.rac_sequence.signal

// 第三步: 訂閱信號(hào),激活信號(hào)施掏,會(huì)自動(dòng)把集合中的所有值钮惠,遍歷出來。

[numbers.rac_sequence.signal subscribeNext:^(id x) {

NSLog(@"%@",x);

}];

// 2.遍歷字典,遍歷出來的鍵值對(duì)會(huì)包裝成RACTuple(元組對(duì)象)

NSDictionary *dict = @{@"name":@"HMJ",@"age":@18};

[dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {

// 解包元組七芭,會(huì)把元組的值素挽,按順序給參數(shù)里面的變量賦值

RACTupleUnpack(NSString *key, NSString *value) = x;

// 相當(dāng)于以下寫法

//??????? NSString *key = x[0];

//??????? NSString *value = x[1];

NSLog(@"%@ %@",key,value);

}];

3.字典轉(zhuǎn)模型

3.1 OC寫法

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

NSMutableArray *items = [NSMutableArray array];

for (NSDictionary *dict in dictArr) {

FlagItem *item = [FlagItem flagWithDict:dict];

[items addObject:item];

}

3.2 RAC寫法

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

NSMutableArray *flags = [NSMutableArray array];

_flags = flags;

// rac_sequence注意點(diǎn):調(diào)用subscribeNext,并不會(huì)馬上執(zhí)行nextBlock狸驳,而是會(huì)等一會(huì)预明。

[dictArr.rac_sequence.signal subscribeNext:^(id x) {

// 運(yùn)用RAC遍歷字典,x:字典

FlagItem *item = [FlagItem flagWithDict:x];

[flags addObject:item];

}];

NSLog(@"%@",? NSStringFromCGRect([UIScreen mainScreen].bounds));

3.3 RAC高級(jí)寫法:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];

NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];

// map:映射的意思耙箍,目的:把原始值value映射成一個(gè)新值

// array: 把集合轉(zhuǎn)換成數(shù)組

// 底層實(shí)現(xiàn):當(dāng)信號(hào)被訂閱撰糠,會(huì)遍歷集合中的原始值,映射成新值究西,并且保存到新的數(shù)組里。

NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {

return [FlagItem flagWithDict:value];

}] array];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末物喷,一起剝皮案震驚了整個(gè)濱河市卤材,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌峦失,老刑警劉巖扇丛,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異尉辑,居然都是意外死亡帆精,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門隧魄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卓练,“玉大人,你說我怎么就攤上這事购啄〗笃螅” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵狮含,是天一觀的道長顽悼。 經(jīng)常有香客問我,道長几迄,這世上最難降的妖魔是什么蔚龙? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮映胁,結(jié)果婚禮上木羹,老公的妹妹穿的比我還像新娘。我一直安慰自己解孙,他們只是感情好汇跨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布务荆。 她就那樣靜靜地躺著,像睡著了一般穷遂。 火紅的嫁衣襯著肌膚如雪函匕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天蚪黑,我揣著相機(jī)與錄音盅惜,去河邊找鬼。 笑死忌穿,一個(gè)胖子當(dāng)著我的面吹牛抒寂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掠剑,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屈芜,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了朴译?” 一聲冷哼從身側(cè)響起井佑,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眠寿,沒想到半個(gè)月后躬翁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盯拱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年盒发,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狡逢。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宁舰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奢浑,到底是詐尸還是另有隱情明吩,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布殷费,位于F島的核電站印荔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏详羡。R本人自食惡果不足惜仍律,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望实柠。 院中可真熱鬧水泉,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炕横,卻和暖如春源内,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背份殿。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工膜钓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卿嘲。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓颂斜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拾枣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沃疮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容