pragma mark ----方法1
- (void)testOne{
//总之:先订阅 再发送 订阅后才会触发^RACDisposable *(id<RACSubscriber> subscriber){}这个block
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//发送信号
[subscriber sendNext:@"发送信号"];
//不在发送信号,最好发送完成
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
// NSLog(@"信号被销毁了");
}];
}];
//订阅信号
[signal subscribeNext:^(id x) {
//这里接受拿到发送的信号
NSLog(@"%@",x); //发送信号
}];
[signal subscribeError:^(NSError *error) {
//错误信息
}];
}
#pragma mark ----方法2
- (void)testTwo{
RACSubject *subject = [RACSubject subject];
[subject subscribeNext:^(id x) {
NSLog(@"第一个订阅者%@",x);
}];
[subject subscribeNext:^(id x) {
NSLog(@"第2个订阅者%@",x);
}];
[subject sendNext:@"4555"];
[subject sendCompleted];
}
#pragma mark ---方法3 元组(数组使用)
- (void)test3{
RACTuple *tuple=[RACTuple tupleWithObjectsFromArray:@[@"123",@"345",@1]];
NSString *first=tuple[0];
NSLog(@"%@",first);
//数组
NSArray *arr=@[@"213",@"321",@1];
[arr.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"高级写法遍历数组%@",x);
}];
//字典
NSDictionary *dict=@{@"sex":@"女",@"name":@"打交道的",@"age":@18};
//转换成集合
[dict.rac_sequence.signal subscribeNext:^(id x) {
RACTupleUnpack(NSString *key,NSString *value)=x;
NSLog(@"%@ %@",key,value);
}];
}
#pragma mark ---//RACMulticastConnection用于相当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
- (void)test4{
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"1"];//发送消息,订阅者接受消息
return [RACDisposable disposableWithBlock:^{
}];
}];
//订阅信息-运行结果,会执行两遍发送请求,也就是每次订阅都会发送一次请求
[signal subscribeNext:^(id x) {
NSLog(@"接受消息");
}];
[signal subscribeNext:^(id x) {
NSLog(@"接受消息");
}];
//解决重复问题
RACSignal *connectionSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"接受请求");
return [RACDisposable disposableWithBlock:^{
}];
}];
//创建连接
RACMulticastConnection *connection = [connectionSignal publish];
[connection.signal subscribeNext:^(id x) {
NSLog(@"第一个信号");
}];
[connection.signal subscribeNext:^(id x) {
NSLog(@"第二个信号");
}];
[connection connect];
}
#pragma mark ----RACCommand:RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程-使用场景:监听按钮点击,网络请求
- (void)test5{
//创建命令
RACCommand *command=[[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");
//创建信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"请求数据"];
//注意:数据传递完,最好用sendCompleted,这时命令才执行完
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"数据销毁");
}];
}];
}];
//强引用命令,,不要被销毁,否则接收不到消息
command=command;
[command.executing subscribeNext:^(id x) {
if ([x boolValue]==YES) {
NSLog(@"当前正在执行");
}else{
NSLog(@"执行完成/没有执行");
}
}];
//执行命令
[command execute:@1];
}
#pragma mark ----代替代理方法
- (void)btnClick{
NSLog(@"ahgagagh");
}
到这里是高级用法
import "myTestViewController.h"
#import <ReactiveCocoa/ReactiveCocoa.h>
#import "FlagItem.h"
@interface myTestViewController ()
@property (nonatomic,strong) NSMutableArray *dataArray;
@property (nonatomic,strong) RACCommand *command;
@end
@implementation myTestViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor cyanColor];
[self testPlist];
}
- (void)testPlist{
NSBundle * bundle = [NSBundle mainBundle];
NSString * path = [bundle pathForResource:@"test.plist" ofType:nil];
NSLog(@"%@",path);
NSArray *arr = [NSArray arrayWithContentsOfFile:path];
for (NSDictionary *str in arr) {
NSLog(@"======%@",str);
}
}
- (void)ReactiveCocoaUseDetail{
// ReactiveCocoa开发中常见用法。
// 1 代替代理:
//比如我现在写一个redview 控制redview中的按钮的点击事件
// rac_signalForSelector:用于替代代理。
// 2 代替KVO :
// rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变。
// 3 监听事件:
// rac_signalForControlEvents:用于监听某个事件。
// 4 代替通知:
// rac_addObserverForName:用于监听某个通知。
// 5 监听文本框文字改变:
// rac_textSignal:只要文本框发出改变就会发出这个信号。
// 6 处理当界面有多次请求时,需要都获取到数据时,才能展示界面
// rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。
// 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
}
//RACCommand RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,可以很方便的监控事件的执行过程。
- (void)mycocoaTestRACCommand{
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
NSLog(@"执行命令");
// 创建空信号,用来传递数据
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"请求数据"];
// 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
[subscriber sendCompleted];
return nil;
}];
}];
// 强引用命令,不要被销毁,否则接收不到数据
_command = command;
// 3.订阅RACCommand中的信号
[command.executionSignals subscribeNext:^(id x) {
[x subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}];
}
//RACSequence和RACTuple简单使用
- (void)mycocoaTestRACSequence{
// 1.遍历数组
NSArray *numbers = @[@1,@2,@3,@4];
// 这里其实是三步
// 第一步: 把数组转换成集合RACSequence numbers.rac_sequence
// 第二步: 把集合RACSequence转换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) {
// 解包元组,会把元组的值,按顺序给参数里面的变量赋值
RACTupleUnpack(NSString *key,NSString *value) = x;
// 相当于以下写法
// NSString *key = x[0];
// NSString *value = x[1];
NSLog(@"%@ %@",key,value);
}];
//3. 最终我是要将字典转为模型的 这里就写一个RAC字典转模型的写法
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
NSMutableArray *flags = [NSMutableArray array];
_dataArray = flags;
// rac_sequence注意点:调用subscribeNext,并不会马上执行nextBlock,而是会等一会。
[dictArr.rac_sequence.signal subscribeNext:^(id x) {
// 运用RAC遍历字典,x:字典
FlagItem *item = [FlagItem flagWithDict:x];
[self.dataArray addObject:item];
}];
//还有一个高级的写法 如下:
//map 是映射的意思 目的:把原始值value映射成一个新值 也就是给模型赋值
NSArray *flags2 = [[dictArr.rac_sequence map:^id(id value) {
return [FlagItem flagWithDict:value];
}] array];
}
- (void)mycocoaTestRACSubject{
//创建信号
RACSubject *subject = [[RACSubject alloc] init];
//订阅信号
[subject subscribeNext:^(id x) {
//这里只有发送完信号,才会来
NSLog(@"第一个订阅者");
}];
[subject subscribeNext:^(id x) {
//这里只有发送完信号,才会来
NSLog(@"第二个订阅者");
}];
//发送信号
//会遍历信号的订阅着 完事儿之后才会 触发订阅者的block
[subject sendNext:[NSMutableArray arrayWithObjects:@1,@2,@3,nil]];
/*
RACSubject 也可以用作代理 例如:
//这是第一个控制器
@implementation OneViewController
- (IBAction)btnClick:(id)sender {
// 创建第二个控制器
TwoViewController *twoVc = [[TwoViewController alloc] init];
// 设置代理信号
twoVc.delegateSignal = [RACSubject subject];
// 订阅代理信号
[twoVc.delegateSignal subscribeNext:^(id x) {
NSLog(@"点击了通知按钮"); 这里可以通过这个 id 把需要的数据传过去
}];
// 跳转到第二个控制器
[self presentViewController:twoVc animated:YES completion:nil];
}
**********************************************************************
//第二个控制中
步骤二:监听第二个控制器按钮点击
@implementation TwoViewController
- (IBAction)notice:(id)sender {
// 通知第一个控制器,告诉它,按钮被点了
// 通知代理
// 判断代理信号是否有值
if (self.delegateSignal) {
// 有值,才需要通知
[self.delegateSignal sendNext:nil]; 这里拿到第一个控制器传过来的数据
}
}
**/
}
- (void)mycocoaTestRACSignal{
//1 创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//2 发送信号 这里我猜测应该是使用的KVO添加的监听着 底层应该就是用的这个方法 addObserver:<#(nonnull NSObject *)#> forKeyPath:<#(nonnull NSString *)#> options:<#(NSKeyValueObservingOptions)#> context:<#(nullable void *)#>
[subscriber sendNext:@123];
return [RACDisposable disposableWithBlock:^{
//信号取消或者 信号错误发生错误 回来到这里block
}];
}];
//3 激活信号
[signal subscribeNext:^(id x) {
//每当有信号发出数据,就会调用block. 这里我猜测应该是 KVO用来监听信号的变化,也就是说,如果信号没有发生改变,这里是不会走的, block不会执行
NSLog(@"%s",__func__);
}];
}
- (void)btnClick:(UIButton *)sender{
}
@end
网友评论