函数式编程思想: 把操作尽量写成一系例嵌套的函数或者方法调用。
函数式编程本质: 就是往方法中传入Block,方法中嵌套Block调用,把代码聚合起来管理
函数式编程特点: 每个方法必须有返回值(本身对象),把函数或者Block当做参数,block参数(需要操作的值)block返回值(操作结果)
代表:ReactiveCocoa。
链式编程思想:是将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好。a(1).b(2).c(3)
链式编程特点:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)
代表:Masonry框架。
##ReactiveCocoa常见类
学习框架首要之处:个人认为先要搞清楚框架中常用的类,在RAC中最核心的类
RACSiganl,搞定这个类就能用ReactiveCocoa开发了。
- RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。
注意:
- 信号类(
RACSiganl),只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出。
- 默认一个信号都是冷信号,也就是值改变了,也不会触发,只有订阅了这个信号,这个信号才会变为热信号,值改变了才会触发。
- 如何订阅信号:调用信号
RACSignal的subscribeNext就能订阅
- RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据。- `objc
 -(void)createSimpleSignal{
 // RACSignal使用步骤:
 // 1.创建信号 + (RACSignal )createSignal:(RACDisposable (^)(id- subscriber))didSubscribe 
 // 2.订阅信号,才会激活信号. - (RACDisposable * )subscribeNext:(void (^)(id x))nextBlock
 // 3.发送信号 - (void)sendNext:(id)value
  // RACSignal底层实现:
  // 1.创建信号,首先把didSubscribe保存到信号中,还不会触发。
  // 2.当信号被订阅,也就是调用signal的subscribeNext:nextBlock
  // 2.2 subscribeNext内部会创建订阅者subscriber,并且把nextBlock保存到subscriber中。
  // 2.1 subscribeNext内部会调用siganl的didSubscribe
  // 3.siganl的didSubscribe中调用[subscriber sendNext:@1];
  // 3.1 sendNext底层其实就是执行subscriber的nextBlock
  //    1.创建信息
  RACSignal  signal =  [RACSignal createSignal:^RACDisposable  _Nullable(id
    // block调用时刻:每当有订阅者订阅信号,就会调用block。
    //        2.发送信号
    [subscriber sendNext:@1];
    // 如果不在发送数据,最好发送信号完成,内部会自动调用[RACDisposable disposable]取消订阅信号。
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
  // block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号。
  // 执行完Block后,当前信号就不在被订阅了。
  NSLog(@"信号销毁了");
}];
  }];
  //    3. 订阅信号,才会激活信号
  [signal subscribeNext:^(id   x) {
     // block调用时刻:每当有信号发出数据,就会调用block.
   NSLog(@”接收到数据:%@”,x);
  }];
}
3. `RACDisposable`:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。
**使用场景**: 不想监听某个信号时,可以通过它主动取消订阅信号。
4. `RACSubject`: 信号提供者,自己可以充当信号,又能发送信号。
**使用场景**: 通常用来代替代理,有了它,就不必要使用代理了
1. `RACReplaySubject`:重复提供信号类,`RACSubject`的子类。
> `RACReplaySubject`可以先发送信号,在订阅信号,`RACSubject`就不可以
**使用场景一**:如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复提供信号类。
**使用场景二**:可以设置capacity数量来限制缓存的value的数量,即只缓充最新的几个值。
```objc
-(void)createRACSubject{
  // RACSubject使用步骤
  // 1.创建信号 [RACSubject subject],跟RACSiganl不一样,创建信号时没有block。
  // 2.订阅信号 - (RACDisposable * ) subscribeNext:(void (^)(id x))nextBlock
  // 3.发送信号 sendNext:(id)value
  // RACSubject:底层实现和RACSignal不一样。
  // 1.调用subscribeNext订阅信号,只是把订阅者保存起来,并且订阅者的nextBlock已经赋值了。
  // 2.调用sendNext发送信号,遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock
  //1. 创建信号
  RACSubject * subject = [RACSubject subject];
  //2.订阅信号
  [subject subscribeNext:^(id   x) {
    // block调用时刻:当信号发出新值,就会调用.
    NSLog(@"第一个订阅都:%@",x);
  }];
  [subject subscribeNext:^(id   x) {
    // block调用时刻:当信号发出新值,就会调用.
    NSLog(@"第二个订阅都:%@",x);
  }];
  //3. 发送信息
  [subject sendNext:@"1"];
}
-(void)createReplaySubject{
  // RACReplaySubject使用步骤:
  // 1.创建信号 [RACSubject subject],跟RACSiganl不一样,创建信号时没有block。
  // 2.可以先订阅信号,也可以先发送信号。
  // 2.1 订阅信号 - (RACDisposable * )subscribeNext:(void (^)(id x))nextBlock
  // 2.2 发送信号 sendNext:(id)value
  // RACReplaySubject:底层实现和RACSubject不一样。
  // 1.调用sendNext发送信号,把值保存起来,然后遍历刚刚保存的所有订阅者,一个一个调用订阅者的nextBlock。
  // 2.调用subscribeNext订阅信号,遍历保存的所有值,一个一个调用订阅者的nextBlock
  // 如果想当一个信号被订阅,就重复播放之前所有值,需要先发送信号,在订阅信号。
  // 也就是先保存值,在订阅值。
  //    1.创建信号
  RACReplaySubject * replaySuject = [RACReplaySubject subject];
  //    2. 发送信号
  [replaySuject sendNext:@1];
  [replaySuject sendNext:@2];
  //    3.订阅信号
  [replaySuject subscribeNext:^(id   x) {
    NSLog(@"第一个订阅者接收到的数据%@",x);
  }];
  [replaySuject subscribeNext:^(id   x) {
    NSLog(@" 第二个订阅者接收到的数据%@",x);
  }];
}
- RACTuple:元组类,类似- NSArray,用来包装值.
- RACSequence:RAC中的集合类,用于代替- NSArray,- NSDictionary,可以使用它来快速遍历数组和字典。- `objc
 -( void )RACIterator{
 // 1.遍历数组
 NSArray * numbers = @[@1,@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”:@”yuanph”,@”age”:@18,@”country”:@”china”};
 [dict.rac_sequence.signal subscribeNext:^(RACTuple x) {- // 解包元组,会把元组的值,按顺序给参数里面的变量赋值 RACTupleUnpack(NSString * key,NSString * value)= x; NSLog(@"%@:%@",key,value);- }]; 
 }
`
- RACCommand:- RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程
 使用场景:监听按钮点击,网络请求
 
                     
                     
                