ReactiveCocoa使用详解01

2018-03-19  本文已影响13人  TitanCoder

ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的函数式响应式编程框架,它提供了一系列用来组合和转换值流的 API

一. 什么是响应式变成思想?

学习一个框架之前, 首先要了解这个框架的编程思想, 这里在介绍响应式编程思想之前, 先介绍一下之前接触过的编程思想

1.面向对象

2. 面向过程

3. 链式编程思想

4. 函数式编程思想

5. 函数式编程思想

6. ReactiveCocoa编程思想

所以, ReactiveCocoa被描述为函数响应式编程(FRP)框架, 下面具体介绍一下RAC的一些常见类

二. RACSiganl 信号类

- (void)test2 {
    //创建信号
    RACSignal *single = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        //发送消息
        [subscriber sendNext:@"a"];
        [subscriber sendNext:@"b"];
        //发送完成
        [subscriber sendCompleted];
        
        //清空数据
        return [RACDisposable disposableWithBlock:^{
            //当订阅者被消耗的时候就会执行
            //当订阅者发送完成,或者error的时候也会执行
            NSLog(@"RACDisposable的block");
        }];
    }];
    
    //订阅信号
    RACDisposable *disposable = [single subscribeNext:^(id  _Nullable x) {
        NSLog(@"value = %@", x);
    } error:^(NSError * _Nullable error) {
        NSLog(@"error: %@", error);
    } completed:^{
        NSLog(@"completed");
    }];
    
    //释放
    [disposable dispose];
}

RACSignal在创建信号的时候,底层会调用RACDynamicSignalcreateSignal的方法, 如下:

+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
    return [RACDynamicSignal createSignal:didSubscribe];
}

这里的block是一个 id<RACSubscriber> 类型的subscriber, 而这个RACSubscriber, 我们可以点进去看一些底层实现, 协议方法如下:

@protocol RACSubscriber <NSObject>
@required

/// Sends the next value to subscribers.
- (void)sendNext:(nullable id)value;

/// Sends the error to subscribers.
- (void)sendError:(nullable NSError *)error;

/// Sends completed to subscribers.
- (void)sendCompleted;

/// Sends the subscriber a disposable that represents one of its subscriptions.
- (void)didSubscribeWithDisposable:(RACCompoundDisposable *)disposable;

三. 信号提供者: RACSubject

1. RACSubject简单使用

- (void)setRacSubject1 {
    //先订阅, 在发送信号
    //1. 创建信号
    RACSubject *subject = [RACSubject subject];
    
    //2. 订阅
    //内部创建RACSubscriber
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"第一个订阅者--%@", x);
    }];
    
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"第二个订阅者---%@", x);
    }];

    //3. 发送信号
    //遍历所有的订阅者, 执行nextBlock
    [subject sendNext:@2];
    
    /** 打印结果
     2018-03-17 20:18:19.782119+0800 ReactiveObjc[23883:1420936] 第一个订阅者--2
     2018-03-17 20:18:19.784715+0800 ReactiveObjc[23883:1420936] 第二个订阅者---2
     */
}

2. RACReplaySubject简单使用

- (void)setReplaySubject {
    //创建信号
    RACReplaySubject *replySub = [RACReplaySubject subject];
    
    //发送信号
    [replySub sendNext:@23];
    [replySub sendNext:@34];
    
    //订阅信号
    // 遍历值,让一个订阅者去发送多个值
    // 只要订阅一次,之前所有发送的值都能获取到.
    [replySub subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@", x);
    }];
    
    /**
     2018-03-19 12:01:14.112253+0800 ReactiveObjc[5130:446958] 23
     2018-03-19 12:01:14.112511+0800 ReactiveObjc[5130:446958] 34
     */
}

3. 替代代理/通知

3-1. 下面看一下代理的简单使用

在自定义View中设置协议

#import <UIKit/UIKit.h>

@class SubjectView;
@protocol SubjectDelegate <NSObject>

@optional
- (void)viewWithTap:(SubjectView *)subView;

@end

@interface SubjectView : UIView

@property (nonatomic, weak) id<SubjectDelegate> delegate;


@end

在vc中, 遵循代理, 并实现代理方法

/// 代理方法
-(void)viewWithTap:(SubjectView *)subView{
    NSLog(@"完成代理, 点击了view");
    
    UIColor *color = [UIColor colorWithRed:(arc4random() % 255) / 255.0 green:(arc4random() % 255) / 255.0 blue:(arc4random() % 255) / 255.0 alpha:1.0];
    self.view.backgroundColor = color;
}

3-1. RACSubject代替代理

在自定义SubjectView.h文件中

#import <UIKit/UIKit.h>
#import <ReactiveObjC.h>

@interface SubjectView : UIView

@property (nonatomic, strong) RACSubject *subject;

@end

在自定义SubjectView.m文件中

#import "SubjectView.h"

@implementation SubjectView

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //发送信号
    [_subject sendNext:self];
}

@end

下面看一下在vc中的操作

- (void)setupSubjectView {
    SubjectView *subV = [[SubjectView alloc]init];
    subV.backgroundColor = [UIColor redColor];
    subV.frame = CGRectMake(100, 100, 100, 100);
    RACSubject *subject = [RACSubject subject];
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"完成代理, 点击了view");
        
        UIColor *color = [UIColor colorWithRed:(arc4random() % 255) / 255.0 green:(arc4random() % 255) / 255.0 blue:(arc4random() % 255) / 255.0 alpha:1.0];
        self.view.backgroundColor = color;
    }];
    subV.subject = subject;
    [self.view addSubview:subV];
}
上一篇 下一篇

猜你喜欢

热点阅读