美文网首页
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实战2

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