| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- //
- // RACQueueScheduler.m
- // ReactiveObjC
- //
- // Created by Josh Abernathy on 11/30/12.
- // Copyright (c) 2012 GitHub, Inc. All rights reserved.
- //
- #import "RACQueueScheduler.h"
- #import "RACDisposable.h"
- #import "RACQueueScheduler+Subclass.h"
- #import "RACScheduler+Private.h"
- @implementation RACQueueScheduler
- #pragma mark Lifecycle
- - (instancetype)initWithName:(NSString *)name queue:(dispatch_queue_t)queue {
- NSCParameterAssert(queue != NULL);
- self = [super initWithName:name];
- _queue = queue;
- #if !OS_OBJECT_USE_OBJC
- dispatch_retain(_queue);
- #endif
- return self;
- }
- #if !OS_OBJECT_USE_OBJC
- - (void)dealloc {
- if (_queue != NULL) {
- dispatch_release(_queue);
- _queue = NULL;
- }
- }
- #endif
- #pragma mark Date Conversions
- + (dispatch_time_t)wallTimeWithDate:(NSDate *)date {
- NSCParameterAssert(date != nil);
- double seconds = 0;
- double frac = modf(date.timeIntervalSince1970, &seconds);
- struct timespec walltime = {
- .tv_sec = (time_t)fmin(fmax(seconds, LONG_MIN), LONG_MAX),
- .tv_nsec = (long)fmin(fmax(frac * NSEC_PER_SEC, LONG_MIN), LONG_MAX)
- };
- return dispatch_walltime(&walltime, 0);
- }
- #pragma mark 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;
- }
- - (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block {
- NSCParameterAssert(date != nil);
- NSCParameterAssert(block != NULL);
- RACDisposable *disposable = [[RACDisposable alloc] init];
- dispatch_after([self.class wallTimeWithDate:date], self.queue, ^{
- if (disposable.disposed) return;
- [self performAsCurrentScheduler:block];
- });
- return disposable;
- }
- - (RACDisposable *)after:(NSDate *)date repeatingEvery:(NSTimeInterval)interval withLeeway:(NSTimeInterval)leeway schedule:(void (^)(void))block {
- NSCParameterAssert(date != nil);
- NSCParameterAssert(interval > 0.0 && interval < INT64_MAX / NSEC_PER_SEC);
- NSCParameterAssert(leeway >= 0.0 && leeway < INT64_MAX / NSEC_PER_SEC);
- NSCParameterAssert(block != NULL);
- uint64_t intervalInNanoSecs = (uint64_t)(interval * NSEC_PER_SEC);
- uint64_t leewayInNanoSecs = (uint64_t)(leeway * NSEC_PER_SEC);
- dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
- dispatch_source_set_timer(timer, [self.class wallTimeWithDate:date], intervalInNanoSecs, leewayInNanoSecs);
- dispatch_source_set_event_handler(timer, block);
- dispatch_resume(timer);
- return [RACDisposable disposableWithBlock:^{
- dispatch_source_cancel(timer);
- }];
- }
- @end
|