美文网首页
RAC实战2

RAC实战2

作者: 小怪兽鱼小宝 | 来源:发表于2019-04-22 13:26 被阅读0次

这部分主要分析下RACDisposable对象。还是上次的代码,只不过上次在创建信号的block中我们返回了nil,这次返回一个RACDisposable对象。

 //1、创建信号量
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        NSLog(@"创建信号量");
        
        //3、发布信息
        [subscriber sendNext:@"I'm send next data"];
        
        NSLog(@"那我啥时候运行");
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"disposable");
        }];
    }];
    
    //2、订阅信号量
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

到disposableWithBlock方法里面看看,创建了RACDisposable对象,用这个block做了初始化(把这个block保存到_disposeBlock属性里)。

+ (instancetype)disposableWithBlock:(void (^)(void))block {
    return [[self alloc] initWithBlock:block];
}
- (instancetype)initWithBlock:(void (^)(void))block {
    NSCParameterAssert(block != nil);

    self = [super init];

    _disposeBlock = (void *)CFBridgingRetain([block copy]); 
    OSMemoryBarrier();

    return self;
}

那这个block什么时候会被调用呢?
1 订阅者被销毁
2 RACDisposable 调用dispose取消订阅

第一种情况,如果我们强引用这个subscriber,这个block不会被调用。

先添加一个属性
@property (strong,nonatomic) id<RACSubscriber> subscriber;
//1、创建信号量
RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
    NSLog(@"创建信号量");
        
    //3、发布信息
    [subscriber sendNext:@"I'm send next data"];
    self.subscriber = subscriber;    //强引用
    NSLog(@"那我啥时候运行");
        
    return [RACDisposable disposableWithBlock:^{
            NSLog(@"disposable");
        }];
    }];
    
    //2、订阅信号量
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
}];

这个时候就不会输出disposable。说明打印disposable的block也没有被调用。
下面通过代码分析下为什么会这样。上一讲里面说过subscribeNext:方法里面会生成一个RACSubscriber对象,并且会调用生成信号的时候传递过来的bloc(以RACSubscriber对象作为block参数),这个block会被执行,打印了"创建信号量"等字符串。这个block以RACSubscriber对象作为参数(其实满足RACSubscriber协议就行,这里RACSubscriber类就满足RACSubscriber协议),返回RACDisposable类型的对象。创建RACDisposable对象的时候传递了一个block,这个block为什么在订阅者subscriber销毁的时候被调用呢。我们继续看代码

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

在订阅者被销毁的时候,会调用订阅者持有的disposable对象的dispose方法。

- (void)dispose {
    void (^disposeBlock)(void) = NULL;

    while (YES) {
        void *blockPtr = _disposeBlock;
        if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
            if (blockPtr != (__bridge void *)self) {
                disposeBlock = CFBridgingRelease(blockPtr);
            }

            break;
        }
    }

    if (disposeBlock != nil) disposeBlock();
}

最终还是调用了创建RACDisposable对象的时候传入的block,所以就打印了“ disposable”。
第二种情况是直接调用了这个dispose方法,也会执行创建RACDisposable对象的时候传入的block,所以就打印了“ disposable”。

参考文章
https://www.jianshu.com/p/187a889285db

相关文章

  • RAC实战

    RAC实战 RAC实战 - 专题 - 简书 RAC(ReactiveCocoa)学习资源汇总~持续更新 - CSD...

  • RAC实战2

    这部分主要分析下RACDisposable对象。还是上次的代码,只不过上次在创建信号的block中我们返回了nil...

  • 2018-11-12

    iOS MVVM+RAC 从框架到实战 - 简书

  • rac实战

    http://www.cocoachina.com/industry/20140609/8737.html

  • 2019-12-10

    iOS MVVM+RAC 从框架到实战 http://www.cocoachina.com/articles/18659

  • RAC(四)

    本demo详见github 1.RAC+MVVM 2.RAC+MVVM-网络请求 友情链接: RAC(一) RAC...

  • RAC(三)

    本demo详见github 1.RAC过滤 2.RAC映射 3.RAC组合 4.RACBind 友情链接: RAC...

  • MVVM

    iOS MVVM+RAC 从框架到实战 【长篇高能】ReactiveCocoa 和 MVVM 入门 iOS 最全R...

  • iOS开发之RAC的用法

    一、RAC简介 1、RAC全称:ReactiveCocoa, Github 一个开源框架 2、ReactiveCo...

  • iOS开发之RAC(一)初级篇

    一、RAC是什么? 1、RAC全称:ReactiveCocoa, Github 一个开源框架!! 2、Reacti...

网友评论

      本文标题:RAC实战2

      本文链接:https://www.haomeiwen.com/subject/cpgkgqtx.html