iOS开发之RAC---ReactiveCocoa

1.监听成员变量变化,当成员变量值被改变时触发,其实就是KVO机制使用场景,
通常有三个步骤

  <1>. 给对象的成员变量添加监听
  <2>. 实现监听回调
  <3>. 取消监听;

而通过 RAC也可以实现,RAC的回调是通过block实现的

egOne: 值变化时发送一个请求,每次值被修改时就会调用此block,并把修改后的参数传进来

    [RACObserve(self, self.navigationTitle) subscribeNext:^(NSString *x) {
        [self questWithData];
}];

egOne:当一个titile为标题时发送请求

  [[RACObserve(self, self.navigationTitle)
filter:^(NSString* value) {
    if ([value hasPrefix:@"标题"]) {
        return YES;
    } else { return NO;
    }
}]
subscribeNext:^(NSString * x) {
    [self requestWithData];
}];

egThree:关于textfield的处理
平常我们检测textfield的变化都是这样

 [self.accountText addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
- (void)textFieldDidChange:(UITextField *)textField {
if (textField == self.textfield ) {
    if (self.textfield.length >= 11 ) {
    [self requestWithData];
    } else {
       return NO;
    }
   }
}

现在我们使用RAC监听textfield的值的变化
// filter:满足了某一条件才往下执行,通过条件才执行subscribeNext 这个block,才执行下一步
[[self.textField.rac_textSignal filter:^(NSString *value) {
if (value.length != 13) {
return NO;
} else { return YES; }
}]
subscribeNext:^(NSString *x) {
[self requestWithData];
}];

egFour:
// 监听多个变量变化,当变量满足条件时,使button为可点击状态

    [[RACSignal
  combineLatest:@[self.nameText.rac_textSignal,
                  self.passText.rac_textSignal,
                  RACObserve(self, isConnected)
                  ]
  reduce:^(NSString *name, NSString *pass, NSNumber *connect){
      return @(name.length > 0 && pass.length > 0 && ![connect boolValue]);
  }]
 subscribeNext:^(NSNumber *res){
     if ([res boolValue]) {
         NSLog(@"XXXXX send request");
     }
 }];
RACSignal�:

// RACSignal对象捕捉当前和未来的值。信号可以被观察者链接,组合和反应。信号实际上不会执行,直到它被订阅。
// RACSignal是个信号量类,他的基类RACStream,信号量类继承自流类,RACSequence也继承自RACStream,是RAC框架的数组类,
// 发送事件流给它的subscriber。目前总共有三种类型的事件:next、error、completed。一个signal在因error终止或者完成前,可以发送任意数量的next事件,subscribeNext事件发生时,方法中对应的block也会执行
// 使用category来为很多基本UIKit控件添加signal

//eg:RACSequence与NSArray的转换
NSArray *arr = @[@(1),@(2),@(3),@(4),@(5)];
RACSequence *seque = [arr rac_sequence]; // arr -> RACSequence
NSArray *arr2 = [seque array];   //  RACSequence -> arr

RACSignal与RACSequence都属于流类,都继承于RACStream,他们有个共同的流动性特性, RACSequence属于人流车流的流动,RACSignal属于信号流

下面贴一段关于信号流使用详解的代码
//  getRandomSiganl获取随机数的信号量
//  createSignal只有在有人订阅时才会执行
//  subscriber信号量的订阅者
//  当有人订阅这个信号量时 [subscriber sendNext:@(arc4random())];
RACSignal *getRandomSiganl = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [subscriber sendNext:@(arc4random())];
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        
    }];
}];

// 订阅操作:subscribeNext
[getRandomSiganl subscribeNext:^(id x) {
    
}];

[getRandomSiganl subscribeNext:^(id x) {
    
}];
冷信号与热信号
//  冷信号默认什么都不做
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [subscriber sendNext:@"subscribe"];
    [subscriber sendCompleted];
    return nil;
}];
//  加了下面的代码变成了热信号,block里的代码就会被执行
//  我们只是创建了一个signal,但因为没有subscribe,所以什么都不会发生
[signal subscribeCompleted:^{

}];

// 创建信号的另一种方式

RACSignal *abc = [@"a,b,c" componentsSeparatedByString:@","].rac_sequence.signal;
[abc subscribeNext:^(id x) {
    NSLog(@"abc:%@",x);
}];

// UIView Categories
// 常用的UIView也都相应的category,比如UIAlertView,就不需要再用Delegate了

UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"" message:@"" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:@"ensure", nil];
[[alertView rac_buttonClickedSignal] subscribeNext:^(id x) {
    NSLog(@"x:%@",x);
}];
[alertView show
 ];

// UITableView
// rac_prepareForReuseSignal,它的作用是当cell即将要被重用时,告诉cell上有多个button,cell在初始化时给每个button都addTarget:action:forControlEvents,但被重用时需要先移除这些target,只要添加如下代码便可解决这个问题

[[[self.button
   rac_signalForControlEvents:UIControlEventTouchUpInside]
  takeUntil:self.rac_prepareForReuseSignal]
 subscribeNext:^(UIButton *x) {
     NSLog(@"x:%@",x);
 }];

// Map:用来改变流中的值并用结果创建一个新的流
// 可以使用map操作来把接收的数据转换成想要的类型,只要它是个对象。

RACSequence *seque = [@"A,B,C" componentsSeparatedByString:@","].rac_sequence;
RACSequence *map = [seque map:^id(id value) {
    return [value stringByAppendingString:value];
}];
NSLog(@"map:%@",map); // reson is AA BB CC

// Filter:用一个block来判断test每一个值,判断通过就把这个值加入到结果的流中

RACSequence *num = [@"1,2,3" componentsSeparatedByString:@","].rac_sequence;
RACSequence *fiter = [num filter:^BOOL(NSString *value) {
    return (value.intValue % 2) == 0;
}];
NSLog(@"filter:%@",fiter); // reson is 2

// Concat:方法将一个流中的值加到另一个中

RACSequence *sequen = [@"A,B,C" componentsSeparatedByString:@","].rac_sequence;
RACSequence *number = [@"1,2,3" componentsSeparatedByString:@","].rac_sequence;
RACSequence *connect = [sequen concat:number];
NSLog(@"connect:%@",connect);// reson is A B C 123

// 补充,非原创

  //  补充,非原创:     ReactiveCocoa

// RACSignal: 信号类,表示当数据改变时,信号内部会发出数据,本身不具备发送信号的能力,而是交给一个内部的订阅者去发出
// 默认一个信号都是冷信号,也就是值改变了也不会触发,只有订阅了这个信号才会变成热信号,然后值改变了才会触发
// 订阅信号: subscribeNext

// 1.RACSubscriber : 订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助它发送数据
// 2.RACDisposable : 用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它; 不想监听某个信号时,可以通过它主动取消订阅信号
// 3.RACSubject : 信号提供者,自己可以充当信号,又能发送信号; 通常用来代替代理,有了它,就不用自定义代理
// 4.RACReplaySubject : 重复提供信号类,RACSubject的子类
// ***RACReplaySubject与RACSubject区别: RACReplaySubject可以先发送信号,在订阅信号,RACSubject就不可以。
// 使用场景一:如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。
// 使用场景二:可以设置capacity数量来限制缓存的value的数量,即只缓充最新的几个值。

// RACSequence和RACTuple简单使用
// 字典转模型

 //    NSArray *numArr = @[@1,@2,@3,@4];
//    //  把数组转化成RACSequence numArr.rac_sequence
//    [numArr.rac_sequence.signal subscribeNext:^(id x) {
//        NSLog(@"numArr.rac_sequence.signal:%@",x);
//    }];

// // 遍历字典,遍历出来的键值对会包装成RACTuple(元祖对象)

//    NSDictionary *dic = @{@"name":@"LiHua",@"age":@18};
//    [dic.rac_sequence.signal subscribeNext:^(id x) {
//       //  解包元组,会把元组的值,按顺序给参数里面的变量赋值
//        RACTupleUnpack(NSString *key,NSString *value) = x;
//        //  相当于: //        NSString *key = x[0];   NSString *value = x[1];
//        NSLog(@"key:%@,value:%@",key,value);
//    }];
RACCommand

调用执行成功返回信号的信号,主线程执行

 @property (nonatomic, strong, readonly) RACSignal *executionSignals;

调用执行当前信号是否正在执行返回@(NO),主线程执行

@property (nonatomic, strong, readonly) RACSignal *executing;

默认情况下返回@NO信号,但只有一下两种情况会返回@YES

1.上面第二种创建RACCommand的时候就给isEnableSignal赋值为@YES的时候   
2.allowsConcurrentExecution属性设置为 NO并且这个信号正在执行中. 主线程执行
@property (nonatomic, strong, readonly) RACSignal *enabled;

是否允许多个RACCommand同时执行。

@property (atomic, assign) BOOL allowsConcurrentExecution;

执行RACCommand的时候发送获取的error信号

@property (nonatomic, strong, readonly) RACSignal *errors;

调用RACCommand,input为executionSignals的订阅者发送的值

- (RACSignal *)execute:(id)input;

你可能感兴趣的:(iOS开发之RAC---ReactiveCocoa)