RAC高級用法###
1. rac_liftSelector
它的作用是盟步,當(dāng)我們在并行執(zhí)行多個任務(wù)的時候,需要等所有任務(wù)都執(zhí)行完成后,再來處理后面的任務(wù)澳眷。假設(shè)要請求一個頁面的數(shù)據(jù),可能有的時候需要請求幾個接口疏魏,需要等所有的請求都完成了以后才刷新UI停做。
具體用法:
-(void)rac_liftDemo{
//請求1
RACSignal * signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//發(fā)送請求
NSLog(@"請求網(wǎng)絡(luò)數(shù)據(jù) 1");
//發(fā)送數(shù)據(jù)
[subscriber sendNext:@"數(shù)據(jù)1 來了"];
return nil;
}];
//請求2
RACSignal * signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//發(fā)送請求
NSLog(@"請求網(wǎng)絡(luò)數(shù)據(jù) 2");
//發(fā)送數(shù)據(jù)
[subscriber sendNext:@"數(shù)據(jù)2 來了"];
return nil;
}];
//數(shù)組:存放信號
//當(dāng)數(shù)組中的所有信號都發(fā)送了數(shù)據(jù),才會執(zhí)行Selector
//方法的參數(shù):必須和數(shù)組的信號一一對應(yīng)!!
//方法的參數(shù):就是每一個信號發(fā)送的數(shù)據(jù)!!
[self rac_liftSelector:@selector(updateUIWithOneData:TwoData:) withSignalsFromArray:@[signal1,signal2]];
}
- (void)updateUIWithOneData:(id )oneData TwoData:(id )twoData {
NSLog(@"%@",[NSThread currentThread]);
//拿到數(shù)據(jù)更新UI
NSLog(@"UI!!%@%@",oneData,twoData);
}
2.RAC常用的宏
- RAC:給某個對象綁定一個屬性!
具體示例:假設(shè)我們監(jiān)聽一個UITextField的文本框內(nèi)容,把他的內(nèi)容賦值給UILabel的text屬性大莫。我們之前的寫法是這樣的:
[_textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
_label.text = x;
}];
那么使用RAC這個宏 我們可以寫成這樣
//給某個對象的某個屬性綁定信號,一旦信號產(chǎn)生數(shù)據(jù),就會將內(nèi)容賦值給屬性!
RAC(_label,text) = _textField.rac_textSignal;
- RACObserve:監(jiān)聽某個對象的屬性蛉腌。
//只要這個對象的屬性發(fā)生變化..哥么信號就發(fā)送數(shù)據(jù)!!
[RACObserve(self.label, text) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
- RACTuplePack:將數(shù)據(jù)打包成RACTuple。
//包裝元祖
RACTuple * tuple = RACTuplePack(@1,@2);
NSLog(@"%@",tuple[0]);
- RACTupleUnpack:解包只厘。
//字典
NSDictionary * dict = @{@"name":@"hank",@"age":@"18"};
//字典轉(zhuǎn)集合
[dict.rac_sequence.signal subscribeNext:^(RACTuple* x) {
// NSString * key = x[0];
// NSString * value = x[1];
// NSLog(@"%@%@",key,value);
//RACTupleUnpack:用來解析元祖
//宏里面的參數(shù),傳需要解析出來的變量名稱
// = 右邊,放需要解析的元祖
RACTupleUnpack(NSString * key,NSString * value) = x;
NSLog(@"%@ : %@",key,value);
}];
- weakify strongify:打斷引用者鏈條烙丛。
我們的RAC大多數(shù)都用到block,既然用到block就會存在強引用的問題羔味,假設(shè)我們的RACSignal被強引用了河咽,此時我們的控制器退出后并不會執(zhí)行dealloc。 使用 weakify strongify 打斷引用者鏈條介评,就能好的解決這個問題库北。
@interface ModalViewController ()
/** */
@property(nonatomic,strong)RACSignal * signal;
@end
@implementation ModalViewController
- (IBAction)dismiss:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
@weakify(self);
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
@strongify(self);
NSLog(@"%@",self);
[subscriber sendNext:@"發(fā)送數(shù)據(jù)"];
return nil;
}];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
_signal = signal;
}
//對象被釋放!!
- (void)dealloc {
NSLog(@"這個控制器走了!不送!!");
}
@end
3.RACMulticastConnection
連接類:用于當(dāng)一個信號被多次訂閱的時候,避免多次調(diào)用創(chuàng)建信號的Block
在某些應(yīng)用場景中,我們可能需要在多個地方訂閱同一個信號们陆,這樣就會導(dǎo)致信號會被執(zhí)行多次寒瓦,而我們往往只需要執(zhí)行一次,其他的訂閱你直接發(fā)送數(shù)據(jù)給我就可以了坪仇。那么這就需要使用 RACMulticastConnection--這個連接類杂腰。
//不管訂閱多少次信號,就只會請求一次數(shù)據(jù)
//RACMulticastConnection:必須要有信號
//1.創(chuàng)建信號
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//發(fā)送網(wǎng)絡(luò)請求
NSLog(@"發(fā)送請求");
//發(fā)送數(shù)據(jù)
[subscriber sendNext:@"請求到的數(shù)據(jù)"];
return nil;
}];
//2.將信號轉(zhuǎn)成連接類!!
RACMulticastConnection *connection = [signal publish];
//3.訂閱連接類的信號
[connection.signal subscribeNext:^(id _Nullable x) {
NSLog(@"A處在處理數(shù)據(jù)%@",x);
}];
[connection.signal subscribeNext:^(id _Nullable x) {
NSLog(@"B處在處理數(shù)據(jù)%@",x);
}];
//4.連接
[connection connect];
4.RACCommand 命令
基本用法:
//1.創(chuàng)建命令
RACCommand * command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"%@",input);
//input:指令
//
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
//發(fā)送數(shù)據(jù)
[subscriber sendNext:@"執(zhí)行完命令之后產(chǎn)生的數(shù)據(jù)"];
return nil;
}];
}];
//2.執(zhí)行命令
RACSignal * signal = [command execute:@"輸入的指令!!"];
//3.訂閱信號!
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
5.bind 綁定
基本用法
//1.創(chuàng)建信號
RACSubject * subject = [RACSubject subject];
//2.綁定信號
RACSignal * bindSignal = [subject bind:^RACSignalBindBlock _Nonnull{
return ^RACSignal * (id value, BOOL *stop){
//block調(diào)用:只要源信號發(fā)送數(shù)據(jù),就會調(diào)用bindBlock
//block作用:處理原信號內(nèi)容
//value:源信號發(fā)送的內(nèi)容
NSLog(@"%@",value);
//返回信號,不能傳nil , 返回空信號 :[RACSignal empty]
return [RACReturnSignal return:value];
};
}];
//3.訂閱信號
[bindSignal subscribeNext:^(id _Nullable x) {
NSLog(@"綁定接收到!! %@",x);
}];
//4.發(fā)送
[subject sendNext:@"發(fā)送原始的數(shù)據(jù)"];