ReactiveCocoa 学习笔记九(RACDisposable)

RACDisposable

RACDisposable 是 ReactiveCocoa 中十分常见的类,其封装了注销订阅者时所要做的工作。

该类的方法十分简单,一个用来创建实例,封装要做的操作,一个执行操作。

+ (instancetype)disposableWithBlock:(void (^)(void))block;

- (void)dispose;

在该类中,有一个实例变量 _disposeBlock ,其是默认指向 self 的指针,在初始化后,其指向待执行的代码块。

- (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();
}

在 dispose 方法中,会调用 OSAtomicCompareAndSwapPtrBarrier() 函数,该函数会判断 blockPtr 所指向的地址是否与 &_disposeBlock 内存地址中存储的指针地址相同,若相同,则将 NULL 保存到 &_disposeBlock 内存地址中。

即当 blockPtr == *(&_disposeBlock) 为 YES 时,并且 blockPtr 并不是指向 self 时,则其所指向的代码块便会被执行,执行完毕后,代码块即可被释放。

RACCompoundDisposable

RACCompoundDisposable 是 RACDisposable 的子类,其可以包含多个 RACDisposable 实例,用来保存多个待处理的任务。

为了更快的访问待处理的任务,在该类中声明了一个 _inlineDisposables 指针,其指向一个包含有 RACCompoundDisposableInlineCount 个 RACDisposable 实例的数组,该值默认为 2 ,当添加的任务超过该值时,便会创建额外的数组进行保存。

#if RACCompoundDisposableInlineCount
RACDisposable *_inlineDisposables[RACCompoundDisposableInlineCount];
#endif
	
CFMutableArrayRef _disposables;

该类提供了两个创建实例的类方法:

+ (instancetype)compoundDisposable;

+ (instancetype)compoundDisposableWithDisposables:(nullable NSArray *)disposables;

得到实例对象后,可以调用下面的方法添加任务,如果当前组合任务已经被执行了,那么待添加的任务也会立刻执行。

- (void)addDisposable:(nullable RACDisposable *)disposable;

无论组合的任务处于什么状态,都可以调用下面的方法移除指定的任务,如果任务不存在,那么则直接返回。

- (void)removeDisposable:(nullable RACDisposable *)disposable;

该类还重写了 dispose 方法,调用时,该类实例会调用自身所包含的所有任务的 dispose 方法。

这些方法的执行都是线程安全的,因为该类声明了一个变量锁,保证其线程安全性。

pthread_mutex_t _mutex;

const int result __attribute__((unused)) = pthread_mutex_init(&_mutex, NULL);

所有要求线程安全的代码都包含在锁中:

pthread_mutex_lock(&_mutex);
{
	//代码
}
pthread_mutex_unlock(&_mutex);

RACScopedDisposable

RACScopedDisposable 是 RACDisposable 的子类,其同父类的区别在于其被释放时,在 dealloc 方法中会调用 dispose 方法。

从该类的实例创建方法可知,该类通常是将 RACDisposable 的实例进行封装。

+ (instancetype)scopedDisposableWithDisposable:(RACDisposable *)disposable {
	return [self disposableWithBlock:^{
		[disposable dispose];
	}];
}

RACDisposable 实例对象可以直接调用 asScopedDisposable 实例方法获取一个该类的实例对象。

RACKVOTrampoline

RACKVOTrampoline 是 RACDisposable 的子类,该类将监听目标属性变化的任务进行了封装,当 dispose 方法调用时,便结束该监听任务。

typedef void (^RACKVOBlock)(id target, id observer, NSDictionary *change);

- (instancetype)initWithTarget:(__weak NSObject *)target observer:(__weak NSObject *)observer keyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options block:(RACKVOBlock)block;

RACSerialDisposable

RACSerialDisposable 是 RACDisposable 的子类,该类提供的类方法和实例方法都是针对属性 disposable 的,实际上该类所持有的任务都是存储在 disposable 属性中的。

@property (atomic, strong, nullable) RACDisposable *disposable;

+ (instancetype)serialDisposableWithDisposable:(nullable RACDisposable *)disposable;

//使用新任务替换原任务,如果任务已经执行完毕,那么新任务 newDisposable 立刻执行,
//并且保持属性 disposable 为 nil
- (nullable RACDisposable *)swapInDisposable:(nullable RACDisposable *)newDisposable;

并且,该类重写了 initWithBlock: 方法,将任务封装在了属性 disposable 中。

- (instancetype)initWithBlock:(void (^)(void))block {
	self = [self init];
	if (self == nil) return nil;

	self.disposable = [RACDisposable disposableWithBlock:block];

	return self;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值