一個(gè)倒計(jì)時(shí)管理類--(簡(jiǎn)單的觀察者)

更新:我之前那個(gè)定時(shí)器不知道有沒(méi)有人再用,今天發(fā)現(xiàn)之前寫(xiě)的有點(diǎn)問(wèn)題,定時(shí)器停止不了,原因是吧定時(shí)器加到子線程里,移除是在主線程運(yùn)行的移除。正確的是在加入定時(shí)器的線程中移除定時(shí)器,不然不能正常停止。代碼是沒(méi)更新過(guò)得,大家注意就好了。

場(chǎng)景:最近做的一個(gè)電商項(xiàng)目,很多很多倒計(jì)時(shí),,
當(dāng)我寫(xiě)到第二個(gè)的時(shí)候覺(jué)得還是把定時(shí)的邏輯拿出來(lái)寫(xiě)比較好,想了幾個(gè)方法最后決定用觀察者
這么用的原因:比如一個(gè)發(fā)送驗(yàn)證碼的按鍵想倒數(shù)計(jì)時(shí),其實(shí)這個(gè)按鍵就是想得到一秒一次的一個(gè)提醒,讓它來(lái)刷新UI(當(dāng)然能把我計(jì)數(shù)的秒數(shù)返回來(lái)更好--雖然這會(huì)讓給它發(fā)通知的人責(zé)任更細(xì)化)。這樣看來(lái)這個(gè)場(chǎng)景就非常符合使用觀察者了--“觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新自己”。

步驟一---協(xié)議

/**
 使用者要實(shí)現(xiàn)的協(xié)議
 */
@protocol TimerUserInterface <NSObject>

@property (nonatomic, assign) int allSeconds;//倒計(jì)時(shí)開(kāi)始時(shí)的秒數(shù)
-(void)receivedTimerUpData:(NSString *)timeString;

@end

/**
 定時(shí)器要使用的協(xié)議
 */
@protocol TimerNotifierInterface <NSObject>

-(BOOL)registUser:(id<TimerUserInterface>)timerUser;
-(BOOL)removeUser:(id<TimerUserInterface>)timerUser;
-(void)notifierAllUser;

@end

步驟二---定時(shí)器實(shí)現(xiàn)
定時(shí)器的實(shí)現(xiàn)我用了單例模式保證我只是維護(hù)者一個(gè)定時(shí)器在運(yùn)行這樣在一個(gè)頁(yè)面里有多個(gè)要定時(shí)器的時(shí)候保證消耗小計(jì)時(shí)同步準(zhǔn)確

#import "TimerNotifier.h"

@interface TimerNotifier ()<TimerNotifierInterface>

@property (nonatomic, strong) NSTimer * timer;
@property (nonatomic, strong) NSMutableArray<id<TimerUserInterface>> *timerUsers;

@end

@implementation TimerNotifier

#pragma mark - Init

+(instancetype)standard{
    static TimerNotifier *timerNotifierTool = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timerNotifierTool = [[TimerNotifier alloc] init];
    });
    return timerNotifierTool;
}

-(NSMutableArray *)timerUsers{
    if (nil == _timerUsers) {
        _timerUsers = [[NSMutableArray alloc]init];
    }
    return _timerUsers;
}

-(NSTimer *)timer{
    if (nil == _timer) {
        _timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerDownEvent) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
    return _timer;
}

#pragma mark - Event

-(void)timerDownEvent{
    [self notifierAllUser];
}

-(NSString *)getHourMinutesAndSeconds:(int)totalSeconds{
    int seconds = totalSeconds % 60;
    int minutes = (totalSeconds / 60) % 60;
    int hours = totalSeconds / 3600;
    
    return [NSString stringWithFormat:@"%02d%02d%02d",hours, minutes, seconds];
}

#pragma mark - TimerNotifierInterface

-(BOOL)registUser:(id<TimerUserInterface>)timerUser{
    [self.timerUsers addObject:timerUser];
    if (self.timerUsers.count <= 0) {
        return NO;
    }
    if (self.timerUsers.count == 1) {
        [self.timer fire];
    }
    return YES;
}

-(BOOL)removeUser:(id<TimerUserInterface>)timerUser{
    [self.timerUsers removeObject:timerUser];
    if (self.timerUsers.count == 0) {
        [self.timer timeInterval];
        self.timer = nil;
    }
    return YES;
}

-(void)notifierAllUser{
    [self.timerUsers enumerateObjectsUsingBlock:^(id<TimerUserInterface>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.allSeconds--;
        if (obj.allSeconds == 0) {//倒計(jì)時(shí)結(jié)束后自動(dòng)移除用戶
            [self removeUser:obj];
        }
        NSString *timeStr = [self getHourMinutesAndSeconds:obj.allSeconds];
        [obj receivedTimerUpData:timeStr];
    }];
}

@end

步驟三---使用
使用時(shí)有一個(gè)地方注意因?yàn)槲覀兊膮f(xié)議里帶有一個(gè)屬性所以要用@synthesize allSeconds;聲明下(set get 方法)

self.allSeconds = 120;
    id<TimerNotifierInterface> notiier = (id<TimerNotifierInterface>)[TimerNotifier standard];
    [notiier registUser:self];

//記得不用的時(shí)候移除掉
id<TimerNotifierInterface> notiier = (id<TimerNotifierInterface>)[TimerNotifier standard];
 [notiier removeUser:self];

小白勿噴

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容