self.usernameTextField.rac_textSignal ?輸入框文本變化信號
[[[self.usernameTextField.rac_textSignal
? map:^id(NSString *text) {//map改變了事件傳遞的數(shù)據(jù)????
? ? return @(text.length);
? }] filter:^BOOL(NSNumber *length) {//信號通過條件
? ? return [length integerValue] > 3;
?}] subscribeNext:^(id x) {
?? ?NSLog(@"%@", x); ?}];
RAC宏允許直接把信號的輸出應(yīng)用到對象的屬性上泣港。RAC宏有兩個參數(shù)陡舅,第一個是需要設(shè)置屬性值的對象,第二個是屬性名听绳。每次信號產(chǎn)生一個next事件垃环,傳遞過來的值都會應(yīng)用到該屬性上酪穿,如下:
RAC(self.passwordTextField, backgroundColor) =[validPasswordSignal map:^id(NSNumber *passwordValid) {
? ? ? return [passwordValid boolValue] ? [UIColor clearColor] : [UIColor yellowColor]; ? ?}];
聚合信號;RACSignal *signUpActiveSignal = [RACSignal combineLatest:@[validUsernameSignal, validPasswordSignal] ? ? ? ?????????????????????????reduce:^id(NSNumber *usernameValid, NSNumber *passwordValid) { return @([usernameValid boolValue] && [passwordValid boolValue]);}];
用于監(jiān)聽某個事件:[[self.signInButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"button clicked"); }];
RACObserve(self, name):監(jiān)聽某個對象的某個屬性,返回的是信號晴裹。
[RACObserve(self.view, center) subscribeNext:^(id x) {
?????NSLog(@"%@",x);
?}];
?// 把監(jiān)聽到的通知轉(zhuǎn)換信號
? [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
? ? ? ? NSLog(@"鍵盤彈出");
? ];
創(chuàng)建信號:
-(RACSignal *)signInSignal {
? return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
? ? ????????[self.signInService signInWithUsername:self.usernameTextField.text password:self.passwordTextField.text complete:^(BOOL success)????????{
? ? ? [subscriber sendNext:@(success)];
????????[subscriber sendCompleted];
? ? }];
return nil; }];}
[[[self.signInButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {//附加操作,并不改變事件本身
? ? self.signInButton.enabled = NO;
? ? self.signInFailureText.hidden = YES;
? }]?flattenMap:^id(id x) {//把按鈕點擊事件轉(zhuǎn)換為登錄信號救赐,同時還從內(nèi)部信號發(fā)送事件到外部信號
? ? ???????? return [self signInSignal];
? ? ? ? ?}] subscribeNext:^(id x) {
? ? ???????? NSLog(@"Sign in result: %@", x);
? ???? }];
1: RACSiganl(信號類)只是表示當(dāng)數(shù)據(jù)改變時涧团,信號內(nèi)部會發(fā)出數(shù)據(jù),它本身不具備發(fā)送信號的能力经磅,而是交給內(nèi)部一個訂閱者subscriber去發(fā)出泌绣。2:默認一個信號都是冷信號,就算是值改變了预厌,但你沒有訂閱這個信號的話它也不會觸發(fā)的阿迈,只有訂閱了這個信號,這個信號才會變?yōu)闊嵝盘栐矗蹈淖兞瞬艜|發(fā)
RACSubject(信號提供者)它自己可以充當(dāng)信號苗沧,又能發(fā)送信號(用來代替代理)
RACSequence RAC中的集合類刊棕,可用來快速遍歷數(shù)組,字典待逞!RACTuple RAC中的元組類,類似NSArray,用來包裝值甥角。
?RACSequence的簡單使用:
// 遍歷字典,遍歷出來的鍵值對會包裝成RACTuple(元組對象
? NSDictionary *dict = @{@"name":@"張旭",@"age":@24};
? [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
? ? ? // RACTuple 就是一個元組,元組的概念在Swift有專門的介紹识樱,沒掌握的可以自己上網(wǎng)查一下嗤无!
? ? ? NSLog(@"RACTuple = %@",x);
? ? ? // 解包元組,會把元組的值怜庸,按順序給參數(shù)里面的變量賦值
? ? ? RACTupleUnpack(NSString *key,NSString *value) = x;
? ? ? ?NSLog(@"%@ %@",key,value);
? ?}];
字典轉(zhuǎn)模型RAC高級寫法:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
?NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
?// map:映射的意思当犯,目的:把原始值value映射成一個新值
?// array: 把集合轉(zhuǎn)換成數(shù)組
?// 底層實現(xiàn):當(dāng)信號被訂閱,會遍歷集合中的原始值割疾,映射成新值嚎卫,并且保存到新的數(shù)組里。
NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {
?return [FlagItem flagWithDict:value];
?}] array];
RACCommand:
RAC中用于處理事件的類杈曲,可以把事件如何處理,事件中的數(shù)據(jù)如何傳遞驰凛,包裝到這個類中,他可以很方便的監(jiān)控事件的執(zhí)行過程担扑。
使用場景:監(jiān)聽按鈕點擊恰响,網(wǎng)絡(luò)請求
// 1.創(chuàng)建命令
? ? RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
????????????NSLog(@"執(zhí)行命令");
????????????// 創(chuàng)建空信號,必須返回信號
? ? ? ? ????// ?return [RACSignal empty];
????????// 2.創(chuàng)建信號,用來傳遞數(shù)據(jù)
? ? ? ? return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
?????????????????????[subscriber sendNext:@"請求數(shù)據(jù)"];
????????????????????????// 注意:數(shù)據(jù)傳遞完,最好調(diào)用sendCompleted涌献,這時命令才執(zhí)行完畢胚宦。
? ? ? ? ????????????????? [subscriber sendCompleted];
?????????????????????????return nil;
?}];
}];
// 強引用命令,不要被銷毀燕垃,否則接收不到數(shù)據(jù)
?_conmmand = command;
// 3.訂閱RACCommand中的信號
?[command.executionSignals subscribeNext:^(id x) {
?[x subscribeNext:^(id x) {
?NSLog(@"%@",x);
}];
}];
?// RAC高級用法
? // switchToLatest:用于signal of signals枢劝,獲取signal of signals發(fā)出的最新信號,也就是可以直接拿到RACCommand中的信號
? [command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 4.監(jiān)聽命令是否執(zhí)行完畢,默認會來一次,可以直接跳過卜壕,skip表示跳過第一次信號,take表示接收2次信號
[[[command.executing skip:1] take:2]?subscribeNext:^(id x) {
?if ([x boolValue] == YES) {
? ? ? ? ? ? // 正在執(zhí)行
? ? ? ? ? ? NSLog(@"正在執(zhí)行");
?}else{ // 執(zhí)行完成
? NSLog(@"執(zhí)行完成");
}
}];
? // 5.執(zhí)行命令
?[self.conmmand execute:@1];
RACMulticastConnection:用于當(dāng)一個信號您旁,被多次訂閱時,為了保證創(chuàng)建信號時轴捎,避免多次調(diào)用創(chuàng)建信號中的block鹤盒,造成副作用,可以使用這個類處理侦副。
// RACMulticastConnection:解決重復(fù)請求問題
// 1.創(chuàng)建信號
?RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
?????????NSLog(@"發(fā)送請求");
? ? ? ? [subscriber sendNext:@1];
?????????return nil; }];
?// 2.創(chuàng)建連接
? ? RACMulticastConnection *connect = [signal publish];
?// 3.訂閱信號侦锯,
?// 注意:訂閱信號,也不能激活信號秦驯,只是保存訂閱者到數(shù)組尺碰,必須通過連接,當(dāng)調(diào)用連接,就會一次性調(diào)用所有訂閱者的sendNext:
?[connect.signal subscribeNext:^(id x) {
????????NSLog(@"訂閱者一信號");
}];
[connect.signal subscribeNext:^(id x) {
????NSLog(@"訂閱者二信號");
}];
// 4.連接,激活信號
?[connect connect];
rac_liftSelector:withSignalsFromArray:Signals:處理多個請求,都返回結(jié)果的時候亲桥,統(tǒng)一做處理.
? ? RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
?// 發(fā)送請求1
? ? ? ? [subscriber sendNext:@"發(fā)送請求1"];
? ? ? ? return nil;
? ? }];
RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
? ? ? ? // 發(fā)送請求2
?[subscriber sendNext:@"發(fā)送請求2"];
return nil;
? ? }];
// 使用注意:幾個信號洛心,參數(shù)一的方法就幾個參數(shù),每個參數(shù)對應(yīng)信號發(fā)出的數(shù)據(jù)两曼。
[self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];
- (RACSignal *)then:(RACSignal * (^)(void))block; 這個方法功能是忽略接收者所有的next皂甘,直到信號complete返回一個新的RACSignal,當(dāng)[self rac_signalForSelector:@selector(dismiss:)]信號sendComplete的時候悼凑,執(zhí)行一個block偿枕,這個block必須返回一個不為空的新的RACSignal
[[self rac_signalForSelector:@selector(dismiss:)] then:^RACSignal *{
? ? ? ? @strongify(self);
? ? ? ? return [RACSignal return:self.array];
? ? }];
或者:[[self rac_signalForSelector:@selector(dismiss:)] map:^id(id value) {
? ? ? ? @strongify(self);
? ? ? ? return self.array;
? ? }];
對于需要監(jiān)聽協(xié)議方法的時候可以使用 - (RACSignal *)rac_signalForSelector:(SEL)selector fromProtocol:(Protocol *)protocol?