ReactiveCocoa 学习笔记十(RACScheduler)

RACScheduler

该类用来控制任务的执行,但其是一个抽象类,真正执行操作的是其子类。

执行任务的权限,其实与队列权限相对应。

typedef enum : long {
	RACSchedulerPriorityHigh = DISPATCH_QUEUE_PRIORITY_HIGH,
	RACSchedulerPriorityDefault = DISPATCH_QUEUE_PRIORITY_DEFAULT,
	RACSchedulerPriorityLow = DISPATCH_QUEUE_PRIORITY_LOW,
	RACSchedulerPriorityBackground = DISPATCH_QUEUE_PRIORITY_BACKGROUND,
} RACSchedulerPriority;

这里还定义了一个类型 RACSchedulerRecursiveBlock ,是一个含有一个参数,并且没有返回值的代码块,其包含的参数同样是一个代码块,并且该代码块没有参数和返回值。

typedef void (^RACSchedulerRecursiveBlock)(void (^reschedule)(void));

该类提供了几个类方法以获取实例对象,而其中几个实际返回的是子类的实例对象,并且该对象是全局共享的。

//返回一个 RACImmediateScheduler 全局实例对象,
//其会立刻执行提供的代码块任务
+ (RACScheduler *)immediateScheduler;

//返回一个 RACTargetQueueScheduler 全局实例对象,
//并且任务的执行队列被指定为主队列
+ (RACScheduler *)mainThreadScheduler;

//返回一个 RACSubscriptionScheduler 全局实例对象,
//其有一个 RACScheduler 类型的属性 backgroundScheduler ,
//如果 currentScheduler 为 nil 时,使用该属性对象执行任务
+ (instancetype)subscriptionScheduler;

下面三个方法可归结为第一个方法,最终都返回一个 RACTargetQueueScheduler 实例对象,所有的任务都会加入到全局队列中。

+ (RACScheduler *)schedulerWithPriority:(RACSchedulerPriority)priority name:(nullable NSString *)name;

+ (RACScheduler *)schedulerWithPriority:(RACSchedulerPriority)priority;

+ (RACScheduler *)scheduler;

下面的方法用来获取当前保存的 RACScheduler 实例对象,可知,当保存值为空时,其会判断是否返回指定主队列的实例对象。

+ (RACScheduler *)currentScheduler {
	RACScheduler *scheduler = NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey];
	if (scheduler != nil) return scheduler;
	if ([self.class isOnMainThread]) return RACScheduler.mainThreadScheduler;

	return nil;
}

该类还定义了几个抽象函数,其具体操作由子类实现。

//提供的代码块任务会添加到相应的队列中
- (nullable RACDisposable *)schedule:(void (^)(void))block;

//在指定的时间或之后执行提供的任务,该任务不会影响其他任务
- (nullable RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block;

//延迟指定时间执行所提供的任务,该方法实际会调用上面的方法
- (nullable RACDisposable *)afterDelay:(NSTimeInterval)delay schedule:(void (^)(void))block;

//在指定时间或之后执行提供的任务,并定时重复执行
- (nullable RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block;

下面这个方法可以将递归任务自动转换为循环任务,所以其可以反复的调用自己。

- (nullable RACDisposable *)scheduleRecursiveBlock:(RACSchedulerRecursiveBlock)recursiveBlock;

该方法会执行提供的任务,并且会将当前实例对象暂存为当前线程的 scheduler ,而任务执行结束后,scheduler 会修改回原值或移除。

- (void)performAsCurrentScheduler:(void (^)(void))block {
	NSCParameterAssert(block != NULL);

	RACScheduler *previousScheduler = RACScheduler.currentScheduler;
	NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = self;

	@autoreleasepool {
		block();
	}

	if (previousScheduler != nil) {
		NSThread.currentThread.threadDictionary[RACSchedulerCurrentSchedulerKey] = previousScheduler;
	} else {
		[NSThread.currentThread.threadDictionary removeObjectForKey:RACSchedulerCurrentSchedulerKey];
	}
}

RACImmediateScheduler

RACImmediateScheduler 是 RACScheduler 的子类,其重写了父类的方法,对于提供的任务会立刻执行。

- (RACDisposable *)schedule:(void (^)(void))block {
	NSCParameterAssert(block != NULL);

	block();
	return nil;
}

RACQueueScheduler

RACQueueScheduler 是 RACScheduler 的子类,其重写了父类的方法,会将提供的任务加入指定的队列异步执行。

- (RACDisposable *)schedule:(void (^)(void))block {
	NSCParameterAssert(block != NULL);

	RACDisposable *disposable = [[RACDisposable alloc] init];

	dispatch_async(self.queue, ^{
		if (disposable.disposed) return;
		[self performAsCurrentScheduler:block];
	});

	return disposable;
}

RACTargetQueueScheduler

RACTargetQueueScheduler 是 RACQueueScheduler 的子类,该类重写了父类的方法。

- (instancetype)initWithName:(NSString *)name targetQueue:(dispatch_queue_t)targetQueue {
	NSCParameterAssert(targetQueue != NULL);

	if (name == nil) {
		name = [NSString stringWithFormat:@"org.reactivecocoa.ReactiveObjC.RACTargetQueueScheduler(%s)", dispatch_queue_get_label(targetQueue)];
	}

	dispatch_queue_t queue = dispatch_queue_create(name.UTF8String, DISPATCH_QUEUE_SERIAL);
	if (queue == NULL) return nil;

	dispatch_set_target_queue(queue, targetQueue);

	return [super initWithName:name queue:queue];
}

在该初始化方法中,其主要是创建了一个窜行队列,并且为该窜行队列设置了目标队列。

RACSubscriptionScheduler

RACSubscriptionScheduler 是 RACScheduler 的子类,其重写了父类的方法,会将提供的任务加入指定的队列异步执行,当然,也可能是直接执行任务。

- (RACDisposable *)schedule:(void (^)(void))block {
	NSCParameterAssert(block != NULL);

	if (RACScheduler.currentScheduler == nil) return [self.backgroundScheduler schedule:block];

	block();
	return nil;
}

该类有一个属性 backgroundScheduler ,当全局变量 currentScheduler 为空时,该属性便会被使用。

_backgroundScheduler = [RACScheduler scheduler];

backgroundScheduler 实质上是一个 RACTargetQueueScheduler 实例对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值