.ReactiveCocoa地址
swift
oc
- RACSiganl
RACSiganl是信号类,表示将要有数据传递,只要有数据改变,信号内部接收到数据,就会发出数据。
// 1.创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
// 2.发送信号
NSLog(@"RACSignal");
[subscribersendNext:@"data"];
[subscribersendCompleted];
return [RACDisposable disposableWithBlock:^{
// 信号执行完成
NSLog(@"RACDisposable");
}];
}];
// 3.订阅信号,只有订阅信号,信号才会被激活默认为冷信号
[signalsubscribeNext:^(id _Nullablex) {
NSLog(@"x=%@",x);
}error:^(NSError*_Nullableerror) {
NSLog(@"error");
}completed:^{
NSLog(@"completed");
}];
- RACSubject和RACReplaySubject
RACReplaySubject是RACSubject的子类。
RACReplaySubject可以先发送信号在订阅信号;RACSubject必须先订阅在发送信号
// 必须先订阅在发送信号
// 创建信号
RACSubject *subject = [RACSubject subject];
// 订阅
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
// 发送信号
[subject sendNext:@"data"];
RACReplaySubject *subject = [RACReplaySubject subject];
[subject sendNext:@"123"];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
- RACSubject界面值传递(代理)
TestView.h
#import
#import
#import "ReactiveObjC.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestView : UIView
@property (nonatomic, strong) RACSubject *subject;
@end
NS_ASSUME_NONNULL_END
TestView.m
#import "TestView.h"
@implementation TestView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.subject sendNext:@"123"];
}
@end
Controller代码
TestView *view = [[TestView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
view.backgroundColor = UIColor.blueColor;
[self.view addSubview:view];
RACSubject *subject = [RACSubject subject];
view.subject = subject;
[subject subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
- RACSequence用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典,字典转模型。
//遍历数组
NSArray *ary = @[@"11",@"22",@"33"];
[ary.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
//遍历字典
NSDictionary *dic = @{@"a":@"11",@"b":@"22",@"c":@"33"};
[dic.rac_sequence.signal subscribeNext:^(id _Nullable x) {
RACTupleUnpack(NSString *key, NSString *value) = x;
NSLog(@"%@=%@",key,value);
}];
//字典转模型
NSArray *dicArray = @[@{@"name":@"zhangsan",@"describe":@"zhangsanxxxx"},
@{@"name":@"lisi",@"describe":@"lisixxxx"},
@{@"name":@"wangwu",@"describe":@"wangwuxxxx"}];
NSArray *arrayM = [[dicArray.rac_sequence map:^id _Nullable(id _Nullable value) {
return [TestModel initDic:value];
}] array];
NSLog(@"%@",arrayM);
TestModel
#import
NS_ASSUME_NONNULL_BEGIN
@interface TestModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *describe;
+(instancetype)initDic:(NSDictionary *)dic;
@end
NS_ASSUME_NONNULL_END
#import "TestModel.h"
@implementation TestModel
+(instancetype)initDic:(NSDictionary *)dic{
TestModel *m = [[TestModel alloc] init];
[m setValuesForKeysWithDictionary:dic];
return m;
}
@end
- RACMulticastConnection
RACMulticastConnection:解决RACSignal副作用
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"信号被订阅");
[subscriber sendNext:@"data"];
return nil;
}];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
代码执行结果:信号被订阅打印两次
改进
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
NSLog(@"信号被订阅");
[subscriber sendNext:@"data"];
return nil;
}];
// [signal subscribeNext:^(id _Nullable x) {
// NSLog(@"%@",x);
// }];
//
// [signal subscribeNext:^(id _Nullable x) {
// NSLog(@"%@",x);
// }];
RACMulticastConnection *connection = [signal publish];
[connection.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[connection.signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
[connection connect];
执行结果
- RACCommand
用于处理事件的类,可用于监听按钮点击、网络请求
// 创建RACCommand
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
NSLog(@"RACCommand,%@",input);
// 创建信号
return [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"data"];
[subscriber sendCompleted];
return nil;
}];
}];
//订阅RACCommand中的信号
// [command.executionSignals subscribeNext:^(id _Nullable x) {
//
// NSLog(@"%@",x);
// [x subscribeNext:^(id _Nullable x) {
// NSLog(@"%@",x);
// }];
// }];
//订阅RACCommand中的信号(第二种写法)
[command.executionSignals.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
// 监听命令是否执行完毕,skip表示跳过第一次信号
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
if ([x boolValue]) {
NSLog(@"正在执行");
}else{
NSLog(@"执行完成");
}
}];
// 执行RACCommand
[command execute:@"11"];
- 代替KVO
rac_valuesForKeyPath
@interface ViewController ()
@property (nonatomic, assign) int count;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//KVO
[[self rac_valuesForKeyPath:@keypath(self, count) observer:self] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
self.count++;
}
RACObserve可以监听属性改变
[RACObserve(self, count) subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
rac_signalForControlEvents监听按钮点击事件
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn setTitle:@"点击" forState:(UIControlStateNormal)];
btn.backgroundColor = [UIColor blueColor];
[self.view addSubview:btn];
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@",x);
}];
rac_addObserverForName代替通知
//监听通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"changeName" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
NSLog(@"%@",x);
}];
//发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeName" object:nil userInfo:@{@"name":@"zhangsan"}];
rac_textSignal 监听文本改变
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 44)];
field.backgroundColor = [UIColor yellowColor];
[self.view addSubview:field];
[field.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
rac_liftSelector:withSignalsFromArray:Signals 多个信号发送完成后统一调用
-(void)demo13{
RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"signal1"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id _Nonnull subscriber) {
[subscriber sendNext:@"signal2"];
[subscriber sendCompleted];
return nil;
}];
[self rac_liftSelector:@selector(endMethods:str2:) withSignalsFromArray:@[signal,signal2]];
}
-(void)endMethods:(NSString *)str1 str2:(NSString *)str2{
NSLog(@"str1 =%@",str1);
NSLog(@"str2 =%@",str2);
}
flattenMap,Map
简单使用
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 44)];
field.backgroundColor = [UIColor yellowColor];
[self.view addSubview:field];
[[field.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
return [RACReturnSignal return:[NSString stringWithFormat:@"修改文本框输入的值:%@",value]];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"==%@",x);
}];
[[field.rac_textSignal map:^id _Nullable(NSString * _Nullable value) {
return [NSString stringWithFormat:@"修改文本框输入的值:%@",value];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"==%@",x);
}];
concat
按指定顺序
RACSubject *s1 = [RACReplaySubject subject];
RACSubject *s2 = [RACReplaySubject subject];
RACSubject *s3 = [RACReplaySubject subject];
[s1 sendNext:@"s1"];
[s1 sendCompleted];
[s2 sendNext:@"s2"];
[s2 sendCompleted];
[s3 sendNext:@"s3"];
[s3 sendCompleted];
[[[s2 concat:s3] concat:s1] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
then:
忽略信号
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[[self signal1] then:^RACSignal * _Nonnull{
return [self signal2];
}] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
}
-(RACSignal *)signal1{
RACSubject *signal = [RACReplaySubject subject];
[self loadData1:^(id data) {
//loadDtat2需要loadDtat1的参数可以在此做记录
[signal sendNext:data];
[signal sendCompleted];
}];
return signal;
}
-(RACSignal *)signal2{
RACSubject *signal = [RACReplaySubject subject];
[self loadDtat2:^(id data) {
[signal sendNext:data];
[signal sendCompleted];
}];
return signal;
}
-(void)loadData1:(void(^)(id))success{
success(@"第一个请求数据");
}
-(void)loadDtat2:(void(^)(id))success{
success(@"第二个请求数据");
}
merge
:合并信号,只要任何一个信号发送数据,就能订阅
RACSubject *s1 = [RACReplaySubject subject];
RACSubject *s2 = [RACReplaySubject subject];
RACSubject *s3 = [RACReplaySubject subject];
[s2 sendNext:@"s2"];
[s1 sendNext:@"s1"];
[s3 sendNext:@"s3"];
[[[s3 merge:s1] merge:s2] subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
}];
zipWith
: 压缩信号数据成元组,同时发送数据
RACSubject *s1 = [RACReplaySubject subject];
RACSubject *s3 = [RACReplaySubject subject];
[s1 sendNext:@"s1"];
[s3 sendNext:@"s3"];
[[s3 zipWith:s1] subscribeNext:^(id _Nullable x) {
RACTupleUnpack(NSString *str1, NSString *str2) = x;
NSLog(@"%@ %@",str1,str2);
}];
combineLatestWith
信号合并
UITextField *name = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 44)];
name.backgroundColor = [UIColor yellowColor];
[self.view addSubview:name];
UITextField *pwd = [[UITextField alloc] initWithFrame:CGRectMake(100, 150, 200, 44)];
pwd.backgroundColor = [UIColor yellowColor];
[self.view addSubview:pwd];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
[btn setTitle:@"点击" forState:(UIControlStateNormal)];
btn.backgroundColor = [UIColor blueColor];
[self.view addSubview:btn];
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@",x);
}];
[[name.rac_textSignal combineLatestWith:pwd.rac_textSignal] subscribeNext:^(RACTwoTuple * _Nullable x) {
RACTupleUnpack(NSString *name, NSString *pwd) = x;
btn.enabled = name.length > 0 && pwd.length > 0;
}];
combineLatest
信号合并
UITextField *name = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 44)];
name.backgroundColor = [UIColor yellowColor];
[self.view addSubview:name];
UITextField *pwd = [[UITextField alloc] initWithFrame:CGRectMake(100, 150, 200, 44)];
pwd.backgroundColor = [UIColor yellowColor];
[self.view addSubview:pwd];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
[btn setTitle:@"点击" forState:(UIControlStateNormal)];
btn.backgroundColor = [UIColor blueColor];
[self.view addSubview:btn];
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"%@",x);
}];
[[RACSignal combineLatest:@[name.rac_textSignal,pwd.rac_textSignal] reduce:^id(NSString *name ,NSString *pwd){
return @(name.length > 0 && pwd.length > 0);
}] subscribeNext:^(id _Nullable x) {
btn.enabled = [x boolValue];
}];
精简写法
RAC(btn,enabled) = [RACSignal combineLatest:@[name.rac_textSignal,pwd.rac_textSignal] reduce:^id(NSString *account,NSString *pwd){
return @(account.length > 0 && pwd.length > 0);
}];
filter
过滤
UITextField *name = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 44)];
name.backgroundColor = [UIColor yellowColor];
[self.view addSubview:name];
[[name.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
return value.length > 6 && value.length < 10;
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"%@",x);
}];
最后附上demo地址