RAC系列1之 链式/函数式/响应式编程

注: RAC这一些列文章主要参考了小码哥袁峥雷纯峰这两位大佬的博客

链式编程

提到链式编程我们最常见的就是Masonry框架了,那么我们先来分析一下该框架:

  1. Masonry的分析:
    1. 使用Masonry约束布局步骤
      1. 使用Masonry约束布局步骤
    2. 若使用Masonry,就不能在使用xib/sb,因为该框架内部自动添加有约束
  2. mas_makeConstraints执行流程:
    1. 取消控件自动约束,创建约束制造者MASConstraintMaker,绑定控件,生成了一个保存所有约束的数组
    2. 执行mas_makeConstraints传入进行的block
    3. 让约束制造者安装约束
      1. 清空之前的所有约束(底层用到runtime获得对象的所有约束属性)
      2. 遍历约束数组,一个一个安装
      3. 清空约束数组
  3. 代码举例:

     // 创建红色view
     UIView *redView = [[UIView alloc] init];
     redView.backgroundColor = [UIColor redColor];
     [self.view addSubview:redView];
     // 设置约束,一定要先把view添加上去,才能设置约束
     [redView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.left.top.equalTo(@10);
         make.right.bottom.equalTo(@-10);
            
     }];
    
  4. 我们点击进入查看make.left.top.equalTo(@10);该段代码,可以得出如下结论:
    1. 链式编程思想格式:将各个方法用点语法连接起来.make.left.top.equalTo(@10);
    2. 优点: 将多个操作用”.”连接一起,可读性好
    3. 特点:(这里的block也可以是函数)
      1. 方法的返回值必须为方法的调用者或者block
      2. 若返回为block:把需要操作的值当做block参数,block也需要返回值,就是方法调用者
      3. 方法一定没有输入参数
      4. 方法的实现与block的实现全部在内部,外部只是调用
  5. 举例使用

     //1. 链式编程的实现
     #import <Foundation/Foundation.h>
    
     @interface CalculateManager : NSObject
     //保存计算的结果
     @property (nonatomic,assign) NSInteger result;
     //方法返回block
     -(CalculateManager *(^)(NSInteger))add;
     @end
        
     #import "CalculateManager.h"
     @implementation CalculateManager
     -(CalculateManager* (^)(NSInteger))add{
         //block的实现,block返回方法调用者
         return ^(NSInteger value){
             _result += value;
             return self;
         };
     }
     @end
        
     //ViewController方法中调用
     - (void)test {
         CalculateManager *mag = [[CalculateManager alloc] init];
         mag.add(5).add(6).add(7);
         NSLog(@"====%zd",mag.result);
     }
        
     2.模仿masonry
     //给NSObject分类添加一个加法计算方法
     #import <Foundation/Foundation.h>
     #import "CalculateManager.h"
     @interface NSObject (Caculate)
     //方法的参数为block
     +(NSInteger)zh_makeCaculate:(void(^)(CalculateManager *manager))block;
     @end
        
     #import "NSObject+Caculate.h"
     @implementation NSObject (Caculate)
     +(NSInteger)zh_makeCaculate:(void (^)(CalculateManager *))block{
         //创建block参数
         CalculateManager *magr = [[CalculateManager alloc] init];
         //调用block
         block(magr);
         return magr.result;
     }
     @end
        
        
     //调用
     //模仿masonry
           - (void)test2 {
     //调用NSObject的分类方法,传入block参数
     NSInteger result = [NSObject zh_makeCaculate:^(CalculateManager *manager) {
         //block的内部实现:调用manager的block
         // 用block替代方法
         // 把怎么计算的代码封装到block
     manager.add(5).add(6).add(7);
         }];
         NSLog(@"%zd",result);
    }
    
    

函数式编程

  1. 函数式编程总结:(block也可以是函数)
    1. 样式:一个方法连接一个block实现(一直连续)

       [...[[p 方法:^{
           //代码
       }] 方法:^{
           //代码
       }]...];
      
    2. 函数式编程本质:就是往方法中传入block,方法中嵌套block调用,把代码集合起来管理.
    3. 特点:
      1. 方法返回值一定是对象本身,方法传入参数一定是block
      2. block返回值为计算结果,block参数为操作数
      3. 计算过程在外部,内部调用并接收block的返回值
  2. 举例:

     //用函数式编程实现,写一个加法计算器,并且加法计算器自带判断是否等于某个值
     #import <Foundation/Foundation.h>
    
     @interface CalculateManager : NSObject
     @property (nonatomic, assign) int result;
     @property (nonatomic,assign) BOOL isEqual;
     // 计算
     - (instancetype)calculate:(int(^)(int))calculateBlock;
     // 计算
     - (instancetype)equal:(BOOL(^)(int result))operation;
     @end
        
     #import "CalculateManager.h"
     @implementation CalculateManager
     - (instancetype)calculate:(int (^)(int))calculateBlock
     {
         _result =  calculateBlock(_result);
         return self;
     }
     -(instancetype)equal:(BOOL (^)(int result))operation{
         _isEqual = operation(_result);
         return self;
     }
        
     @end
        
     //调用
     #import "ViewController.h"
     #import "CalculateManager.h"
     @interface ViewController ()
     @end
        
     @implementation ViewController
     - (void)viewDidLoad {
         [super viewDidLoad];
         //获得计算结果
         CalculateManager *mgr = [[CalculateManager alloc] init];
         int result = [[mgr calculate:^(int result){
             // 存放所有的计算代码
             result += 5;
             result *= 5;
             return result;
         }] result];
         NSLog(@"%d",result);
         //计算结果,然后判断是否等于10
         BOOL isEqual = [[[mgr calculate:^int(int result) {
             result += 2;
             result *= 5;
             return result;
         }] equal:^BOOL(int result) {
             return result == 10;
         }] isEqual ];
         NSLog(@"相等吗??%zd",isEqual);
     }
     @end
    
  3. 链式编程与函数式编程比较:
    1. 样式:
      1. 链式编程是将多行代码通过”.”连接在一起,可读性好
      2. 函数式编程是往方法中传入block,方法中嵌套block调用,把代码集合起来管理.
    2. 特点:
      1. 链式返回值是方法调用者或者block,实现在内部,调用在外部,方法无参数
      2. 函数式返回值一定是方法调用者,参数为block,实现在外部,调用在内部

响应式编程

什么是响应式编程?这是一个很抽象的概念,我晕了好久才理解.
知乎上有一位是这样说的:

  1. 响应式编程:顾名思义,就是针对不同的响应来进行编程.
    1. 事件A就几种结果(响应),我们根据不同的结果(响应)进行不同的处理
  2. 响应式编程的必备条件:
    1. 监听事件A有几种结果(响应)
    2. 根据监听,一旦事件A做出某种结果(响应),我们针对不同响应做出不同的事情
  3. 响应式编程的特点:不管你A到底做了什么事,我仅仅关注你A的结果,根据A的不同结果我做不同的事
  4. 响应式编程到处都在,只是我们不能抽象理解:
    1. 同步线程中
         int a = 0;
       //事件A
       {
           //这里处理代码(可能会修改a的值),至于干什么我们不管,只监听a的值
                  
       }
       //这里的if语句就相当于是监听A事件的结果了
       if(a == 0){
           //处理1
       }else if (a == 1){
           //处理2
       }....
      
    2. 异步线程

       int a = 0;
       //事件A:
       {
           //异步网络请求....
           //网请求回来时
           {
               //可能处理a,也可能不处理,我们不管
               //监听: 拿到a的结果,向外界发出通知(通知观察者)
           }
       }
       //其他代码...
              
              
       //观察者:
       {
           //没有通知我(调用我的方法),等待...
           //一旦有结果(得到响应)
           //根据不同响应做不同处理
       }
      
  5. 响应式它是依赖于事件的,响应式的代码它的运行不是按代码的顺序,而是跟多个按时间发生的事件有关.这些按时间排列的事件,被称为”流”,stream
  6. 响应式编程本身是建立于观察者模式之上的一种编程范式.说白了我感觉响应式编程,就是实现观察者模式,时刻监听事件,然后根据监听时刻做出响应.
  7. 在响应式编程中,”监听”流的行为叫做订阅; 执行响应的就是观察者;这个流就是被观察的主体(subject).
  8. 举例:KVO就是响应式编程的体现(不在举例)
Table of Contents