本文是我在学习ReactiveCocoa的过程中的总结记录
一,引入ReactiveCocoa框架
pod 'ReactiveCocoa'
#import <ReactiveCocoa/ReactiveCocoa.h>
二,常见类的使用
1.RACSignal
RACSignal是RAC中最常见的类,做个简单的实验
-(void)testRACSignal
{
//第一步
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号销毁");
}];
}];
//第二步
[signal subscribeNext:^(id x) {
NSLog(@"接收到数据:%@",x);
}];
}
执行这个函数,可以看到结果如下:
2016-02-24 15:11:06.950 FL_RAC_DEMO[101:3360025] 接收到数据:1
2016-02-24 15:11:06.951 FL_RAC_DEMO[101:3360025] 信号被销毁
大致可以理解为,在第一步中,创建一个信号 传入的block是当这个信号被订阅后会自动执行的代码。第二步中订阅了这个信号,此时block执行,其中的[subscriber sendNext:@1];
会被发送给第二步中的block接收。
2.RACSubject
-(void)testRACSubject
{
RACSubject *subject = [RACSubject subject];
[subject subscribeNext:^(id x) {
NSLog(@"第一个订阅者%@",x);
}];
[subject subscribeNext:^(id x) {
NSLog(@"第二个订阅者%@",x);
}];
[subject sendNext:@"1"];
}
执行这个函数,可以看到结果如下:
2016-02-24 15:11:32.114 FL_RAC_DEMO[139:3360495] 第一个订阅者1
2016-02-24 15:11:32.114 FL_RAC_DEMO[139:3360495] 第二个订阅者1
RACSubject可以即使信号发送者,也是信号接受者
在实际使用中常备用来作为代理的替代方式,我们可以做以下实验:
新建一个TestRACSubjectDelegate类
#import <Foundation/Foundation.h>
//引入ReactiveCocoa框架
#import <ReactiveCocoa/ReactiveCocoa.h>
@interface TestRACSubjectDelegate : NSObject
@property(strong,nonatomic)RACSubject *delegateSubject;
@end
#import "TestRACSubjectDelegate.h"
@implementation TestRACSubjectDelegate
- (instancetype)init
{
self = [super init];
if (self) {
_delegateSubject = [RACSubject subject];
[self performSelector:@selector(doSomething) withObject:nil afterDelay:2];
}
return self;
}
-(void)doSomething
{
[_delegateSubject sendNext:@1];
}
@end
在ViewController中
-(void)testRACSubjectAsDelegate
{
TestRACSubjectDelegate *subject = [[TestRACSubjectDelegate alloc] init];
[subject.delegateSubject subscribeNext:^(id x) {
NSLog(@"收到了数据:%@",x);
}];
}
执行这个函数,可以看到结果如下:
2016-02-24 15:28:49.312 FL_RAC_DEMO[489:3371887] 收到了数据:1
所以RACSubject是作为代理的一种很好的替代方式
3.RACCommand
RACCommand可以将某些事件进行包装处理
-(void)testRACCommand
{
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"请求数据"];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号已销毁");
}];
}];
return signal;
}];
//必须对command进行强应用,否则会接收不到数据
_command = command;
[command.executionSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"=>%@",x);
}];
}];
[self.command execute:@1];
}
执行这个函数,可以看到结果如下:
2016-02-24 18:30:51.303 FL_RAC_DEMO[1133:3435749] 执行命令
2016-02-24 18:30:51.311 FL_RAC_DEMO[1133:3435749] =>请求数据
2016-02-24 18:30:51.312 FL_RAC_DEMO[1133:3435749] 信号已销毁
在做网络请求或者对按钮状态处理会经常使用RACCommand
4.其他常用
-(void)testOther
{
//_testView中的按钮点击事件调用clickBtn,可以不实现函数直接在这里被检测到,用来替代代理的功能
[[_testView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
NSLog(@"点击按钮");
}];
// KVO
[[_testView rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 按钮点击事件
[[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"按钮被点击");
}];
// 通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"键盘弹出");
}];
//文本框的文字改变
[_textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@"文字改变了%@",x);
}];
// 多个信号合并处理
RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求1
[subscriber sendNext:@"发送请求1"];
return nil;
}];
RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 发送请求2
[subscriber sendNext:@"发送请求2"];
return nil;
}];
// 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
[self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];
}
五.宏
RAC()
// 只要文本框文字改变,就会修改label的文字
RAC(self.labelView,text) = _textField.rac_textSignal;
RACObserve()
[RACObserve(self.view, center) subscribeNext:^(id x) { NSLog(@"%@",x); }];
网友评论