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 实例对象。