iOS RAC - 定時器

文章系列
《RACSignal 》
《RACDisposable》
《RACSubject、RACReplaySubject》
《iOS RAC - 基本用法》
《iOS RAC - 定時器》
《iOS RAC - RACMulticastConnection》
《iOS RAC - RACCommand》
《iOS RAC - 核心方法bind》
《iOS RAC - 集合RACTuple、RACSequence》
《iOS RAC - rac_leftSelector》
《iOS RAC - 映射》
《iOS RAC - 過濾》
《iOS RAC - 登錄頁面,MVVM》

<br />
結合一個案例去來完成這個功能,完成一個發(fā)送驗證碼的功能。
這里就不討論普通的做法如何去完成這個事情了,直接上RAC代碼。

功能分析:UI上面會有一個button,點擊button發(fā)送驗證碼,并且開始倒計時,在規(guī)定時間內(nèi)不允許在此發(fā)送驗證碼(也就是不允許點擊button

1、搭建UI

UI

2、把button拖入到ViewControlle

引用

3、監(jiān)聽按鈕點擊事件

    [[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
    }];

4、在點擊方法中完成如下代碼

@weakify(self)
    [[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        @strongify(self)
        
        x.enabled = false;
        
        self.time = 10;
        
        //這個就是RAC中的GCD
        self.dispoable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
            _time --;
            NSString * title = _time > 0 ? [NSString stringWithFormat:@"請等待 %d 秒后重試",_time] : @"發(fā)送驗證碼";
            [self.btn setTitle:title forState:UIControlStateNormal | UIControlStateDisabled];
            self.btn.enabled = (_time==0)? YES : NO;
            if (_time == 0) {
                [self.dispoable dispose];
            }
        }];
    }];

運行效果如下:

sendverificationcode.gif

<br />
<br />

可以看到完美的把功能實現(xiàn)了,并且代碼都寫在一塊,但是想去看看內(nèi)部是怎么樣處理的嘛?

開始剖析他:
點擊方法進入內(nèi)部實現(xiàn)


+ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler {
    return [[RACSignal interval:interval onScheduler:scheduler withLeeway:0.0] setNameWithFormat:@"+interval: %f onScheduler: %@", (double)interval, scheduler];
}

點擊進來,發(fā)現(xiàn)調(diào)用的是下面的那個方法

+ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway {
    NSCParameterAssert(scheduler != nil);
    NSCParameterAssert(scheduler != RACScheduler.immediateScheduler);

    return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
        return [scheduler after:[NSDate dateWithTimeIntervalSinceNow:interval] repeatingEvery:interval withLeeway:leeway schedule:^{
            [subscriber sendNext:[NSDate date]];
        }];
    }] setNameWithFormat:@"+interval: %f onScheduler: %@ withLeeway: %f", (double)interval, scheduler, (double)leeway];
}

在這個方法里面創(chuàng)建了一個RACSignal,當外部訂閱的時候就會調(diào)用schedulerafter...方法,在返回的回調(diào)中發(fā)送數(shù)據(jù)。

<br />
到這里為止還是不知道他內(nèi)部的定時器如何實現(xiàn)的,所以進入after...方法內(nèi)部查看。

查看內(nèi)部實現(xiàn)

<br />

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

這里面的紅色部分就是關鍵代碼啦,原來這個里面內(nèi)部就是調(diào)用的GCD的定時器。

  • 定時器的block就是外界傳進來的block
  • 創(chuàng)建一個RACDisposable,調(diào)用disposable方法等時候就會進入創(chuàng)建對象的block,把定時器釋放掉

<br />
最后在文中還使用了兩個宏
@weakify(self)
@strongify(self)

這兩個宏就是為了解決循環(huán)引用的,且必須配套使用。

相當于這樣子的代碼作用

__weak typeof(self) weakSelf = self;
__strong typeof(weakSelf) strongSelf = weakSelf;
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,653評論 3 10
  • 前言 之前對RAC有了一個基本的認識,了解了它的作用,以及RAC的運行機制,我們知道只要是信號(RACSignal...
    大大盆子閱讀 4,616評論 0 11
  • 1.ReactiveCocoa常見操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(RACS...
    萌芽的冬天閱讀 1,144評論 0 5
  • 標簽: iOS RAC 概述 ReactiveCocoa是一個函數(shù)響應式編程框架,它能讓我們脫離Cocoa AP...
    GodyZ閱讀 7,784評論 16 97
  • 前言由于時間的問題,暫且只更新這么多了,后續(xù)還會持續(xù)更新本文《最快讓你上手ReactiveCocoa之進階篇》,目...
    Karos_凱閱讀 1,864評論 0 6

友情鏈接更多精彩內(nèi)容