RACSubscriber
:表示訂閱者的意思,用于發(fā)送信號,這是一個協(xié)議,不是一個類,只要遵守這個協(xié)議,并且實現(xiàn)方法才能成為訂閱者。通過create創(chuàng)建的信號,都有一個訂閱者,幫助他發(fā)送數(shù)據(jù)。
RACDisposable
:用于取消訂閱或者清理資源,當(dāng)信號發(fā)送完成或者發(fā)送錯誤的時候,就會自動觸發(fā)它。
-
使用場景
:不想監(jiān)聽某個信號時,可以通過它主動取消訂閱信號。
RACSubject
:RACSubject:信號提供者,自己可以充當(dāng)信號,又能發(fā)送信號。
-
使用場景
:通常用來代替代理,有了它,就不必要定義代理了。
RACReplaySubject
:重復(fù)提供信號類,RACSubject的子類。
-
RACReplaySubject
與RACSubject
區(qū)別:- RACReplaySubject可以先發(fā)送信號,在訂閱信號,RACSubject就不可以。
使用場景一
:如果一個信號每被訂閱一次,就需要把之前的值重復(fù)發(fā)送一遍,使用重復(fù)提供信號類。使用場景二
:可以設(shè)置capacity數(shù)量來限制緩存的value的數(shù)量,即只緩充最新的幾個值。RACSubject和RACReplaySubject簡單使用:
// RACSubject使用步驟
// 1.創(chuàng)建信號 [RACSubject subject],跟RACSiganl不一樣,創(chuàng)建信號時沒有block。
// 2.訂閱信號 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
// 3.發(fā)送信號 sendNext:(id)value
// RACSubject:底層實現(xiàn)和RACSignal不一樣。
// 1.調(diào)用subscribeNext訂閱信號,只是把訂閱者保存起來,并且訂閱者的nextBlock已經(jīng)賦值了。
// 2.調(diào)用sendNext發(fā)送信號,遍歷剛剛保存的所有訂閱者,一個一個調(diào)用訂閱者的nextBlock。
// 1.創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 2.訂閱信號
[subject subscribeNext:^(id x) {
// block調(diào)用時刻:當(dāng)信號發(fā)出新值,就會調(diào)用.
NSLog(@"第一個訂閱者%@",x);
}];
[subject subscribeNext:^(id x) {
// block調(diào)用時刻:當(dāng)信號發(fā)出新值,就會調(diào)用.
NSLog(@"第二個訂閱者%@",x);
}];
// 3.發(fā)送信號
[subject sendNext:@"1"];
// RACReplaySubject使用步驟:
// 1.創(chuàng)建信號 [RACSubject subject],跟RACSiganl不一樣,創(chuàng)建信號時沒有block。
// 2.可以先訂閱信號,也可以先發(fā)送信號。
// 2.1 訂閱信號 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
// 2.2 發(fā)送信號 sendNext:(id)value
// RACReplaySubject:底層實現(xiàn)和RACSubject不一樣。
// 1.調(diào)用sendNext發(fā)送信號,把值保存起來,然后遍歷剛剛保存的所有訂閱者,一個一個調(diào)用訂閱者的nextBlock。
// 2.調(diào)用subscribeNext訂閱信號,遍歷保存的所有值,一個一個調(diào)用訂閱者的nextBlock
// 如果想當(dāng)一個信號被訂閱,就重復(fù)播放之前所有值,需要先發(fā)送信號,在訂閱信號。
// 也就是先保存值,在訂閱值。
// 1.創(chuàng)建信號
RACReplaySubject *replaySubject = [RACReplaySubject subject];
// 2.發(fā)送信號
[replaySubject sendNext:@1];
[replaySubject sendNext:@2];
// 3.訂閱信號
[replaySubject subscribeNext:^(id x) {
NSLog(@"第一個訂閱者接收到的數(shù)據(jù)%@",x);
}];
// 訂閱信號
[replaySubject subscribeNext:^(id x) {
NSLog(@"第二個訂閱者接收到的數(shù)據(jù)%@",x);
}];
* `RACSubject替換代理`
// 需求:
// 1.給當(dāng)前控制器添加一個按鈕,modal到另一個控制器界面
// 2.另一個控制器view中有個按鈕,點擊按鈕,通知當(dāng)前控制器
步驟一:在第二個控制器.h,添加一個RACSubject代替代理。
@interface TwoViewController : UIViewController
@property (nonatomic, strong) RACSubject *delegateSignal;
@end
步驟二:監(jiān)聽第二個控制器按鈕點擊
@implementation TwoViewController
-
(IBAction)notice:(id)sender {
// 通知第一個控制器,告訴它,按鈕被點了// 通知代理
// 判斷代理信號是否有值
if (self.delegateSignal) {
// 有值,才需要通知
[self.delegateSignal sendNext:nil];
}
}
@end
步驟三:在第一個控制器中,監(jiān)聽跳轉(zhuǎn)按鈕,給第二個控制器的代理信號賦值,并且監(jiān)聽.
@implementation OneViewController
-
(IBAction)btnClick:(id)sender {
// 創(chuàng)建第二個控制器
TwoViewController *twoVc = [[TwoViewController alloc] init];// 設(shè)置代理信號
twoVc.delegateSignal = [RACSubject subject];// 訂閱代理信號
[twoVc.delegateSignal subscribeNext:^(id x) {NSLog(@"點擊了通知按鈕");
}];
// 跳轉(zhuǎn)到第二個控制器
[self presentViewController:twoVc animated:YES completion:nil];
}
@end
`RACTuple`:元組類,類似NSArray,用來包裝值.
`RACSequence`:RAC中的集合類,用于代替NSArray,NSDictionary,可以使用它來快速遍歷數(shù)組和字典。
`使用場景`:1.字典轉(zhuǎn)模型
`RACSequence和RACTuple簡單使用`
// 1.遍歷數(shù)組
NSArray *numbers = @[@1,@2,@3,@4];
// 這里其實是三步
// 第一步: 把數(shù)組轉(zhuǎn)換成集合RACSequence numbers.rac_sequence
// 第二步: 把集合RACSequence轉(zhuǎn)換RACSignal信號類,numbers.rac_sequence.signal
// 第三步: 訂閱信號,激活信號,會自動把集合中的所有值,遍歷出來。
[numbers.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 2.遍歷字典,遍歷出來的鍵值對會包裝成RACTuple(元組對象)
NSDictionary *dict = @{@"name":@"xmg",@"age":@18};
[dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
// 解包元組,會把元組的值,按順序給參數(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ào)用subscribeNext,并不會馬上執(zhí)行nextBlock,而是會等一會。
[dictArr.rac_sequence.signal subscribeNext:^(id x) {
// 運用RAC遍歷字典,x:字典
FlagItem *item = [FlagItem flagWithDict:x];
[flags addObject:item];
}];
NSLog(@"%@", NSStringFromCGRect([UIScreen mainScreen].bounds));
// 3.3 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];
`ok ,那么今天也到這里了,明天繼續(xù)`