RAC初窥

2017-04-21  本文已影响59人  952625a28d0d

先预习一下Block

inlineBlock```

<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
<#statements#>
};```

/**
 *  Block : ARC strong 使用strong就可以 但是非ARC就用copy
 */
@property (nonatomic, copy) void(^JYFBlock)();```

// 1.对象里面包含一个属性 Block作为对象的属性
self.p = [[Person alloc] init];

// Block --inlineBlock
void(^JYFBlock)() = ^() {
    NSLog(@"发哥");
};

self.p.JYFBlock = JYFBlock;


-     作为参数传递

- (void)eat:(void (^)(NSString *))block{
    block(@"香蕉");
}
// 作为参数传递
    self.p = [[Person alloc] init];
    [self.p eat:^(NSString *value){
        NSLog(@"%@", value);
    }];```

    // 只要有返回值的方法 我们都可以使用点语法 那么Get方法之所以能点 就是因为有返回值

- Block作为返回值(扩展非常强!!!)

// 定义一个能够返回Block的Run方法

- (void (^)(int))run{
    return ^(int m){
        NSLog(@"哥们跑起来了 跑了%d",m);
    };
}
self.p = [[Person alloc] init];
    //p.run(3)
    self.p.run(100);```

###RAC
- ReactiveCocoa(RAC) Github上的一个开源框架
- RAC有什么用呢?
    1: 帮助我们更简单霸气地处理事件
    2: 函数响应编程框架


- 1: RACSignal:信号类!通过它创建一个信号
2:通过订阅者订阅刚刚的信号!(变成:热信号)
3:发送信号


RACSignal:信号类 当我们有数据产生的时候 我们就创建一个信号 这个Block需要一个返回值
// 1. 创建信号(冷信号!)
// 被订阅 就会调用
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

    // 3:发送信号subscriber
    [subscriber sendNext:@"呵呵哈哈嘿嘿额"];
    
    return nil;
}];

// 2. 订阅信号(热信号!!)
// 发动的时候才会调用
// 处理数据 展示UI界面
[signal subscribeNext:^(id x) {
   // 订阅信号
    // x: 信号发送的内容!!
    NSLog(@"%@",x);
}];

- RAC原理
1:创建信号RACSignal,底层保存信号Block


2:订阅信号 先创建一个订阅者(RACSubscriber) 然后才去订阅信号 保存了订阅者nextBlock

Paste_Image.png Paste_Image.png Paste_Image.png Paste_Image.png

从源码来看 终于调用了block 那么订阅者接收到了信息

#pragma mark RACSubscriber

- (void)sendNext:(id)value {
    @synchronized (self) {
        void (^nextBlock)(id) = [self.next copy];
        if (nextBlock == nil) return;

        nextBlock(value);
    }
}```


###流程图

![Paste_Image.png](https://img.haomeiwen.com/i189984/6114db92e3f5ad7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###RACDisposable
它可以帮助我们取消订阅,信号发送完毕了,或者失败了,我们都要取消订阅,就像我们注册通知,取消通知一样的道理。

// RACSignal:信号类 当我们有数据产生的时候 我们就创建一个信号 这个Block需要一个返回值
// 1. 创建信号(冷信号!)
// 被订阅 就会调用
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

    // 3:发送信号subscriber 默认一个信号发送完毕 就会取消完毕
    [subscriber sendNext:@"呵呵哈哈嘿嘿额"];
    
    return [RACDisposable disposableWithBlock:^{
        // 只要信号取消订阅 就回来这里
        // 为什么会来这里呢?因为消息发送完毕之后 sub就没了
        // 清空资源
        NSLog(@"哥们取消订阅了");
    }];
}];

// 2. 订阅信号(热信号!!)
// 发动的时候才会调用
// 处理数据 展示UI界面
RACDisposable *disposable = [signal subscribeNext:^(id x) {
   // 订阅信号
    // x: 信号发送的内容!!
    NSLog(@"%@",x);
}];

// 手动取消订阅
[disposable dispose];

###RACSubject:信号提供者!!自己可以充当信号,又能够发送信号

//1:创建信号
RACSubject *subject = [RACSubject subject];

// 2:订阅信号
[subject subscribeNext:^(id x) {
    NSLog(@"接收到了数据%@",x);
}];
// 3: 发送信号
[subject sendNext:@"汉堡包"];```
Paste_Image.png
#pragma mark Lifecycle

+ (instancetype)subject {
    return [[self alloc] init];
}

- (id)init {
    self = [super init];
    if (self == nil) return nil;

    _disposable = [RACCompoundDisposable compoundDisposable];
    _subscribers = [[NSMutableArray alloc] initWithCapacity:1];
    
    return self;
}

- (void)dealloc {
    [self.disposable dispose];
}

1:创建信号(RACSubject)就是创建了一个可变数组,就是我们的Subscribers

- (id)init {
    self = [super init];
    if (self == nil) return nil;

    _disposable = [RACCompoundDisposable compoundDisposable];
    _subscribers = [[NSMutableArray alloc] initWithCapacity:1];
    
    return self;
}

2:订阅信号

- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    return [self subscribe:o];
}```


![Paste_Image.png](https://img.haomeiwen.com/i189984/b90cbb851466b49d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

// 拿到数组
NSMutableArray *subscribers = self.subscribers;
@synchronized (subscribers) {
// 将订阅者保存到数组中
[subscribers addObject:subscriber];
}

return [RACDisposable disposableWithBlock:^{
    @synchronized (subscribers) {
        // Since newer subscribers are generally shorter-lived, search
        // starting from the end of the list.
        NSUInteger index = [subscribers indexOfObjectWithOptions:NSEnumerationReverse passingTest:^ BOOL (id<RACSubscriber> obj, NSUInteger index, BOOL *stop) {
            return obj == subscriber;
        }];

        if (index != NSNotFound) [subscribers removeObjectAtIndex:index];
    }
}];

}


3:发送数据 遍历订阅者对象执行 遍历发送

![Paste_Image.png](https://img.haomeiwen.com/i189984/c396716d22f50cab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


pragma mark RACSubscriber

上一篇 下一篇

猜你喜欢

热点阅读