RACMulticastConnection
:用于當(dāng)一個(gè)信號(hào),被多次訂閱時(shí)杠娱,為了保證創(chuàng)建信號(hào)時(shí)编丘,避免多次調(diào)用創(chuàng)建信號(hào)中的block与学,造成副作用,可以使用這個(gè)類(lèi)處理嘉抓。
使用注意
:RACMulticastConnection通過(guò)RACSignal的-publish或者-muticast:方法創(chuàng)建.
RACMulticastConnection簡(jiǎn)單使用
:
// RACMulticastConnection使用步驟:
// 1.創(chuàng)建信號(hào) + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe
// 2.創(chuàng)建連接 RACMulticastConnection *connect = [signal publish];
// 3.訂閱信號(hào),注意:訂閱的不在是之前的信號(hào)索守,而是連接的信號(hào)。 [connect.signal subscribeNext:nextBlock]
// 4.連接 [connect connect]
// RACMulticastConnection底層原理:
// 1.創(chuàng)建connect抑片,connect.sourceSignal -> RACSignal(原始信號(hào)) connect.signal -> RACSubject
// 2.訂閱connect.signal卵佛,會(huì)調(diào)用RACSubject的subscribeNext,創(chuàng)建訂閱者敞斋,而且把訂閱者保存起來(lái)截汪,不會(huì)執(zhí)行block。
// 3.[connect connect]內(nèi)部會(huì)訂閱RACSignal(原始信號(hào))植捎,并且訂閱者是RACSubject
// 3.1.訂閱原始信號(hào)衙解,就會(huì)調(diào)用原始信號(hào)中的didSubscribe
// 3.2 didSubscribe,拿到訂閱者調(diào)用sendNext焰枢,其實(shí)是調(diào)用RACSubject的sendNext
// 4.RACSubject的sendNext,會(huì)遍歷RACSubject所有訂閱者發(fā)送信號(hào)蚓峦。
// 4.1 因?yàn)閯倓偟诙剑际窃谟嗛哛ACSubject医咨,因此會(huì)拿到第二步所有的訂閱者枫匾,調(diào)用他們的nextBlock
// 需求:假設(shè)在一個(gè)信號(hào)中發(fā)送請(qǐng)求架诞,每次訂閱一次都會(huì)發(fā)送請(qǐng)求拟淮,這樣就會(huì)導(dǎo)致多次請(qǐng)求。
// 解決:使用RACMulticastConnection就能解決.
// 1.創(chuàng)建請(qǐng)求信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"發(fā)送請(qǐng)求");
return nil;
}];
// 2.訂閱信號(hào)
[signal subscribeNext:^(id x) {
NSLog(@"接收數(shù)據(jù)");
}];
// 2.訂閱信號(hào)
[signal subscribeNext:^(id x) {
NSLog(@"接收數(shù)據(jù)");
}];
// 3.運(yùn)行結(jié)果谴忧,會(huì)執(zhí)行兩遍發(fā)送請(qǐng)求很泊,也就是每次訂閱都會(huì)發(fā)送一次請(qǐng)求
// RACMulticastConnection:解決重復(fù)請(qǐng)求問(wèn)題
// 1.創(chuàng)建信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"發(fā)送請(qǐng)求");
[subscriber sendNext:@1];
return nil;
}];
// 2.創(chuàng)建連接
RACMulticastConnection *connect = [signal publish];
// 3.訂閱信號(hào),
// 注意:訂閱信號(hào)沾谓,也不能激活信號(hào)委造,只是保存訂閱者到數(shù)組,必須通過(guò)連接,當(dāng)調(diào)用連接均驶,就會(huì)一次性調(diào)用所有訂閱者的sendNext:
[connect.signal subscribeNext:^(id x) {
NSLog(@"訂閱者一信號(hào)");
}];
[connect.signal subscribeNext:^(id x) {
NSLog(@"訂閱者二信號(hào)");
}];
// 4.連接,激活信號(hào)
[connect connect];
RACCommand
:RAC中用于處理事件的類(lèi)昏兆,可以把事件如何處理,事件中的數(shù)據(jù)如何傳遞,包裝到這個(gè)類(lèi)中妇穴,他可以很方便的監(jiān)控事件的執(zhí)行過(guò)程爬虱。
使用場(chǎng)景
:監(jiān)聽(tīng)按鈕點(diǎn)擊隶债,網(wǎng)絡(luò)請(qǐng)求
RACCommand簡(jiǎn)單使用
// 一、RACCommand使用步驟:
// 1.創(chuàng)建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock
// 2.在signalBlock中跑筝,創(chuàng)建RACSignal死讹,并且作為signalBlock的返回值
// 3.執(zhí)行命令 - (RACSignal *)execute:(id)input
// 二、RACCommand使用注意:
// 1.signalBlock必須要返回一個(gè)信號(hào)曲梗,不能傳nil.
// 2.如果不想要傳遞信號(hào)赞警,直接創(chuàng)建空的信號(hào)[RACSignal empty];
// 3.RACCommand中信號(hào)如果數(shù)據(jù)傳遞完,必須調(diào)用[subscriber sendCompleted]虏两,這時(shí)命令才會(huì)執(zhí)行完畢愧旦,否則永遠(yuǎn)處于執(zhí)行中。
// 三定罢、RACCommand設(shè)計(jì)思想:內(nèi)部signalBlock為什么要返回一個(gè)信號(hào)忘瓦,這個(gè)信號(hào)有什么用。
// 1.在RAC開(kāi)發(fā)中引颈,通常會(huì)把網(wǎng)絡(luò)請(qǐng)求封裝到RACCommand耕皮,直接執(zhí)行某個(gè)RACCommand就能發(fā)送請(qǐng)求。
// 2.當(dāng)RACCommand內(nèi)部請(qǐng)求到數(shù)據(jù)的時(shí)候蝙场,需要把請(qǐng)求的數(shù)據(jù)傳遞給外界凌停,這時(shí)候就需要通過(guò)signalBlock返回的信號(hào)傳遞了。
// 四售滤、如何拿到RACCommand中返回信號(hào)發(fā)出的數(shù)據(jù)罚拟。
// 1.RACCommand有個(gè)執(zhí)行信號(hào)源executionSignals,這個(gè)是signal of signals(信號(hào)的信號(hào)),意思是信號(hào)發(fā)出的數(shù)據(jù)是信號(hào)完箩,不是普通的類(lèi)型赐俗。
// 2.訂閱executionSignals就能拿到RACCommand中返回的信號(hào),然后訂閱signalBlock返回的信號(hào)弊知,就能獲取發(fā)出的值阻逮。
// 五、監(jiān)聽(tīng)當(dāng)前命令是否正在執(zhí)行executing
// 六秩彤、使用場(chǎng)景,監(jiān)聽(tīng)按鈕點(diǎn)擊叔扼,網(wǎng)絡(luò)請(qǐng)求
// 1.創(chuàng)建命令
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"執(zhí)行命令");
// 創(chuàng)建空信號(hào),必須返回信號(hào)
// return [RACSignal empty];
// 2.創(chuàng)建信號(hào),用來(lái)傳遞數(shù)據(jù)
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"請(qǐng)求數(shù)據(jù)"];
// 注意:數(shù)據(jù)傳遞完,最好調(diào)用sendCompleted漫雷,這時(shí)命令才執(zhí)行完畢瓜富。
[subscriber sendCompleted];
return nil;
}];
}];
// 強(qiáng)引用命令,不要被銷(xiāo)毀降盹,否則接收不到數(shù)據(jù)
_conmmand = command;
// 3.執(zhí)行命令
[self.conmmand execute:@1];
// 4.訂閱RACCommand中的信號(hào)
[command.executionSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}];
// RAC高級(jí)用法
// switchToLatest:用于signal of signals与柑,獲取signal of signals發(fā)出的最新信號(hào),也就是可以直接拿到RACCommand中的信號(hào)
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 5.監(jiān)聽(tīng)命令是否執(zhí)行完畢,默認(rèn)會(huì)來(lái)一次,可以直接跳過(guò),skip表示跳過(guò)第一次信號(hào)价捧。
[[command.executing skip:1] subscribeNext:^(id x) {
if ([x boolValue] == YES) {
// 正在執(zhí)行
NSLog(@"正在執(zhí)行");
}else{
// 執(zhí)行完成
NSLog(@"執(zhí)行完成");
}
}];
8.ReactiveCocoa常見(jiàn)宏每辟。
8.1 RAC(TARGET, [KEYPATH, [NIL_VALUE]])
:用于給某個(gè)對(duì)象的某個(gè)屬性綁定。
基本用法
// 只要文本框文字改變干旧,就會(huì)修改label的文字
RAC(self.labelView,text) = _textField.rac_textSignal;
8.2 RACObserve(self, name)
:監(jiān)聽(tīng)某個(gè)對(duì)象的某個(gè)屬性,返回的是信號(hào)渠欺。
基本用法
[RACObserve(self.view, center) subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
8.3 @weakify(Obj)和@strongify(Obj)
,一般兩個(gè)都是配套使用,解決循環(huán)引用問(wèn)題.
8.4 RACTuplePack
:把數(shù)據(jù)包裝成RACTuple(元組類(lèi))
基本用法
// 把參數(shù)中的數(shù)據(jù)包裝成元組
RACTuple *tuple = RACTuplePack(@10,@20);
8.5 RACTupleUnpack
:把RACTuple(元組類(lèi))解包成對(duì)應(yīng)的數(shù)據(jù)。
基本用法
// 把參數(shù)中的數(shù)據(jù)包裝成元組
RACTuple *tuple = RACTuplePack(@"xmg",@20);
// 解包元組椎眯,會(huì)把元組的值挠将,按順序給參數(shù)里面的變量賦值
// name = @"xmg" age = @20
RACTupleUnpack(NSString *name,NSNumber *age) = tuple;
ok,今天學(xué)到這里吧!编整,明天學(xué)習(xí)學(xué)習(xí)MVVM架構(gòu)啦