欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RAC源码分析(一)--RAC基本流程分析

程序员文章站 2024-03-23 22:32:40
...

RAC流程分析

1. 信号产生

实际开发中,一个信号的产生 可以是UI RACobserver Sequence …
下面来看看createSignal都做了什么事情


//1. 
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
    //把block封装进来 利用多态原理返回 RACDynamicSignal
	return [RACDynamicSignal createSignal:didSubscribe];//传入的参数就是一个block
}

//2
+ (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe {
	RACDynamicSignal *signal = [[self alloc] init];
    // 绑定block,在订阅信号的时候调用
	signal->_didSubscribe = [didSubscribe copy];
    
	return [signal setNameWithFormat:@"+createSignal:"];
}


创建了一个信号,并且把didSubscribeBlock保存起来,在信号被订阅的时候,执行这didSubscribeBlock

2. 订阅信号


// 1
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
	NSCParameterAssert(nextBlock != NULL);
	//产生一个订阅者 绑定nextBlock 
	RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    //这是self 是RACDynamicSignal 是本方法的调用者
	return [self subscribe:o];
}


// 2
- (RACDisposable *)subscribe:(id<RACSubscriber>)subscriber {
	NSCParameterAssert(subscriber != nil);
// 产生 RACCompoundDisposable : 核心销毁者
	RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
    
    // RACPassthroughSubscriber 核心订阅者
    /*
     subscriber : 订阅者
     signal : RACDynamicSignal 信号
     disposable : 销毁者
    传入者三个参数后 分别用三个属性保存住
    三个属性保存住 是为了后续使用
    */
	subscriber = [[RACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];

	if (self.didSubscribe != NULL) {
        // RACScheduler(封装了一个GCD)
		RACDisposable *schedulingDisposable = [RACScheduler.subscriptionScheduler schedule:^{
            //把核心订阅者传出去了,  这里的subscriber 就是create信号时block中的参数,订阅者
            //执行创建信号时保存的didSubscribeBlock
			RACDisposable *innerDisposable = self.didSubscribe(subscriber);
            //添加我的要销毁者的对象 把要销毁的对象都装进去 根据情况统一销毁
			[disposable addDisposable:innerDisposable];
		}];

		[disposable addDisposable:schedulingDisposable];
	}
	
	return disposable;
}


  1. 订阅信号,产生了信号的一个订阅者,绑定nextBlock ,在下一步发送信号的时候调用这个nextBlock .
  2. 产生一个核心销毁者(RACCompoundDisposable),产生一个核心订阅者(RACPassthroughSubscriber),核心订阅者保存了销毁者,1中创建的订阅者,以及信号.执行didSubscribe(subscriber)

3.发送信号

- (void)sendNext:(id)value {
	if (self.disposable.disposed) return;

	if (RACSIGNAL_NEXT_ENABLED()) {
		RACSIGNAL_NEXT(cleanedSignalDescription(self.signal), cleanedDTraceString(self.innerSubscriber.description), cleanedDTraceString([value description]));
	}
//真正的订阅 
	[self.innerSubscriber sendNext:value];
}
- (void)sendNext:(id)value {
    //加锁
	@synchronized (self) {
		void (^nextBlock)(id) = [self.next copy];
		if (nextBlock == nil) return;

		nextBlock(value);
	}

互斥锁,然后执行创建订阅者时保存的nextBlock

4. 销毁

在订阅信号的时候,产生了一个核心订阅者(RACPassthroughSubscriber)和一个核心销毁者(RACCompoundDisposable),
而核心订阅者内部持有了订阅者(subscriber),信号(signal),以及核心销毁者(disposable),
核心销毁者(disposable)可以被添加其他的销毁者,存入内部的一个数组中,在自身被释放的时候,会把数组中的也全部释放.
比如订阅者被self持有

[subscriber sendNext:@"123"];
self.subscriber = subscriber;

要想释放掉信号相关的内存,就必须self.subscriber = nil.
当订阅者被释放,在dealloc方法中

- (void)dealloc {
//核心销毁者开始执行dispose方法
	[self.disposable dispose];
}

RAC源码分析(一)--RAC基本流程分析

核心销毁者的dispose

- (void)dispose {
	#if RACCompoundDisposableInlineCount
    //C 数组 type * a[2]
	RACDisposable *inlineCopy[RACCompoundDisposableInlineCount];
	#endif

	CFArrayRef remainingDisposables = NULL;

	pthread_mutex_lock(&_mutex);
	{
		_disposed = YES;

		#if RACCompoundDisposableInlineCount
		for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
			inlineCopy[i] = _inlineDisposables[i];
            //当前的销毁数组,一个个的清理 数组移除
			_inlineDisposables[i] = nil;
		}
		#endif

		remainingDisposables = _disposables;
		_disposables = NULL;
	}
	pthread_mutex_unlock(&_mutex);

	#if RACCompoundDisposableInlineCount
	// Dispose outside of the lock in case the compound disposable is used
	// recursively.
	for (unsigned i = 0; i < RACCompoundDisposableInlineCount; i++) {
		[inlineCopy[i] dispose];//存入的disposable各自调用各自的dispose方法
	}
	#endif

	if (remainingDisposables == NULL) return;

	CFIndex count = CFArrayGetCount(remainingDisposables);
	CFArrayApplyFunction(remainingDisposables, CFRangeMake(0, count), &disposeEach, NULL);
	CFRelease(remainingDisposables);
}

存进核心销毁者的各个disposable调用dispose方法
[RACDisposable dispose]

- (void)dispose {
	void (^disposeBlock)(void) = NULL;
//遍历去找销毁对象
	while (YES) {
		void *blockPtr = _disposeBlock;
//        OSAtomicCompareAndSwapPtrBarrier(v1,v2,v3)
        /*
         v1 与 v3 匹配 相同就返回yes
         然后把v2 赋值给v3 也就是 = null
         */
		if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
			if (blockPtr != (__bridge void *)self) {
				disposeBlock = CFBridgingRelease(blockPtr);
			}

			break;
		}
	}
//    持有的block,成为了临时变量,执行完,block也就释放了
	if (disposeBlock != nil) disposeBlock();
}