导入Reactivecocoa
框架,导入失败在podfile加入use_frameworks
使用的时候 #import “reactiveCocoa.h”
-
RACSignal
信号类 ,只表示当数据发生改变时,他本身不具备发送信号的能力,而是交给内部的订阅者发出 - 默认一个信号都是冷信号,就算值发生改变,也不会发出信号,只有订阅这个信号,信号才能变成热信号,值改变才可以触发
创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// didSubscribe调用:只要一个信号被订阅就会调用
// didSubscribe作用:发送数据
// 发送数据
[subscriber sendNext:@1]
return nil;
}];
订阅信号
[signal subscribeNext:^(id x) {
// nextBlock调用:只要订阅者发送信号就会调用
// nextBlock作用:处理数据,展示在UI上面
// x 就是信号发送的内容
NSLog(@"%@",x);
}];
// 只要订阅者调用sendNext,就会执行nextBlock
// 只要信号被订阅就会执行didSubscribe
RACSubject
:信号的提供者,自己可以充当对象,又可以发送信号,可以代替代理
@interface RACSubject : RACSignal <RACSubscriber>
RACSubject *subject = [RACSubject subject];
// 订阅信号
[subject subscribeNext:^(id x) {
NSLog(@"接受到的数据%@",x);
}];
// 发送信号
[subject sendNext:@1];
// 判断某个方法是否被调用,但是不能传值,如果传值,使用RACSubject
[[self rac_signalForSelector:@selector(didReceiveMemoryWarning)]subscribeNext:^(id x) {
NSLog(@"控制器调用了didReceiveMemoryWarning方法");
}];
#import "NSObject+RACKVOWrapper.h"++++++
一.代替KVO
1. [self.view rac_observeKeyPath:@"bounds" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
}];
2. [[self.view rac_valuesAndChangesForKeyPath:@"frame" options:NSKeyValueObservingOptionNew observer:nil]subscribeNext:^(id x) {
// x:修改的值
}];
二.监听事件
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) {
}];
三.代替通知中心
[[[NSNotificationCenter defaultCenter]rac_addObserverForName:UIKeyboardWillShowNotification object:nil]subscribeNext:^(id x) {
}];
四. 监听文本框
UITextView *textView = [[UITextView alloc]init];
[textView.rac_textSignal subscribeNext:^(id x) {
// x:为文本框的值得改变
}];
五.当一个界面有多次请求的时候,需要保证全部请求完成,才能搭建界面
//请求热销模块
RACSignal *hotSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 请求数据
NSLog(@"请求数据热销模块");
[subscriber sendNext:@"请求数据热销模块"];
return nil;
}] ;
请求最新模块
RACSignal *newSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 请求数据
NSLog(@"请求数据最新模块");
[subscriber sendNext:@"请求数据最新模块"];
return nil;
}] ;
数组:存放信号
// 当数据中的所有信号都发出数据的时候,才会执行Selector:
// 方法的参数必须与数组的信号一一对应
// 方法的参数就是每一个信号发送的数据
[self rac_liftSelector:@selector(Q_updateUIWithHot: newData:) withSignalsFromArray:@[hotSignal,newSignal]];
-(void)Q_updateUIWithHot:(NSString *)hot newData:(NSString *)new
{
NSLog(@"%@++++++%@",hot,new);
}
六.RAC常用的宏
1. 用来给某个对象的某个属性绑定信号,只要产生信号内容,就会把内容给属性赋值
// [_textView.rac_textSignal subscribeNext:^(id x) {
//
// _lable.text = x;
// }];
RAC(_lable.text) = _textView.rac_textSignal;
2. 只要这个对象的属性以改变就会产生信号,监听frame的改变
[RACObserve(self.view, frame) subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
> 3. 产生循环引用,在内强引用,在外弱指针,可以用dealloc方法验证
@weakify(self);
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self);
NSLog(@"%@",self);
return nil;
}];
self.signal = signal;
4.包装元祖宏
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"123",@"we",@"rer"]];
NSString *str = tuple[0];
NSLog(@"%@",str);
RACTuple *tuple = RACTuplePack(@1,@2);
NSLog(@"%@",tuple[0]);
七.RACMulticastConnection 用于当一个信号,被多次订阅,为了保证创建信号时,
避免多次调用创建信号中的block,造成的副作用,可以使用这个类来处理,每次订阅只要拿到数据就可以
创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"发送热门模块的请求");
// 发送数据
[subscriber sendNext:@1];
return nil;
}];
// 订阅信号
[signal subscribeNext:^(id x) {
NSLog(@"订阅者一%@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"订阅者二%@",x);
}];
以下方法可以解决这个问题
1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//didSubscribe什么时候来:连接类连接的时候
NSLog(@"请求数据");
[subscriber sendNext:@1];
return nil;
}];
2.把信号转化为一个连接类
RACMulticastConnection *connect = [signal publish];
3.订阅连接类的信号
[connect.signal subscribeNext:^(id x) {
NSLog(@"订阅者一%@",x);
}];
[connect.signal subscribeNext:^(id x) {
NSLog(@"订阅者二%@",x);
}];
[connect.signal subscribeNext:^(id x) {
NSLog(@"订阅者三%@",x);
}];
4.连接
[connect connect];
八.RACCommand类用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装在这个类中,他可以很方便的监听事件的执行过程,如按钮点击和网络请求
1.创建命令
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
// input:就是执行命令传入参数
// block:执行命令的时候就会被调用
NSLog(@"%@",input);
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"执行命令产生的数据"];
// 当前命令内部发送数据完成,主动发送完成
[subscriber sendCompleted];
return nil;
}];
}];
// 如何拿到执行命令时产生的数据
// 订阅命令每部的信号
>方法一:直接订阅命令执行产生的信号
[[command execute:@1]subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
方法二:executionSignals:信号中的信号,发送的数据就是信号
// 在执行之前订阅
1.[command.executionSignals subscribeNext:^(id x) {
// x:就是信号
[x subscribeNext:^(id x) {
NSLog(@"发送的数据为:%@",x);
}];
}];
方法三
[command.executionSignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
2.[command execute:@1];
<信号中的信号的理解>
创建信号中的信号
RACSubject *signalOfsignal = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
// 方法一
[signalOfsignal subscribeNext:^(RACSubject *x) {
// x:就是signal信号
[x subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}];
// 方法二
[signalOfsignal.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 发送信号
[signalOfsignal sendNext:signal];