詳解iOS中多倒計時場景的解決方案
背景
在我們開發(fā)APP的過程中,或多或少都遇到過需要使用倒計時的場景,大多數(shù)應用中的用戶登錄注冊過程中獲取驗證碼的倒計時,電商或者外賣APP中的訂單送達的倒計時,以及秒殺類APP的秒殺倒計時等。對于這些需要倒計時的場景,通常情況下的解決方案是:在需要展示倒計時的各View模塊各自維護一個自己的倒計時Timer,通過Timer的回調和模塊本身需要的倒計時時間來更新對應View的倒計時的顯示,再在此基礎上加上對應的時間校準方案,一個簡單的倒計時需求就完成了。
問題
對于APP內倒計時的業(yè)務如果只出現(xiàn)在單一的頁面或者是少數(shù)的頁面場景中沒什么太大的問題的,通常對于秒殺類APP的倒計時場景往往是在某個頁面或者某幾個頁面中有多個倒計時共同存在的,這種產品需求的技術展現(xiàn)方式可能是TableView或者CollectionView中的多個Cell,也可能是多個自定義的View模塊,如果我們此時依然使用每個Cell或者每個View模塊各自維護一個單獨的倒計時Timer,當前APP內就會同時存在多個定時器Timer,這對于性能來說是存在一定程度的影響的。那么我們怎么才能更好的解決多倒計時場景的問題呢?

解決方案
既然我們不能讓每一個顯示倒計時的View模塊各自維護一個定時器Timer,那我們就提供一個專門的模塊TimerService來提供倒計時的服務,TimerService內部負責維護唯一一個定時器,同時提供添加和移除監(jiān)聽者的接口以及監(jiān)聽者需要實現(xiàn)的協(xié)議protocol,內部通過HashTable來存儲監(jiān)聽者,每次定時器回調,遍歷所有監(jiān)聽者進行回調,監(jiān)聽者在不需要接收定時器回調的時候只需要從TimerService中移除即可。
TimerService.h對外提供的API和監(jiān)聽者需要實現(xiàn)的協(xié)議主要如下:
//監(jiān)聽者需要實現(xiàn)的協(xié)議 @protocol TimerListener <NSObject> @required - (void)didOnTimer:(TimerService *)timer; @end //對接提供的主要接口 + (instancetype)sharedInstance; - (void)addListener:(id<TimerListener>)listener; - (void)removeListener:(id<TimerListener>)listener;
TimerService.m的內部主要實現(xiàn)如下:
//定時器回調
- (void)onTimer {
[self.map.allObjects enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
id<TimerListener> listener = obj;
if([listener respondsToSelector:@selector(didOnTimer:)]){
[listener didOnTimer:self];
}
}];
}
#pragma mark - public
- (void)addListener:(id<TimerListener>)listener {
TIMER_SERVICE_LOCK(self.operationsLock)
if(![self.map containsObject:listener]){
[self.map addObject:listener];
if(self.map.count > 0){
//啟動
[self startTimer];
}
}
TIMER_SERVICE_UNLOCK(self.operationsLock)
}
- (void)removeListener:(id<TimerListener>)listener {
TIMER_SERVICE_LOCK(self.operationsLock)
if([self.map containsObject:listener]){
[self.map removeObject:listener];
if(self.map.count == 0){
//暫停
[self stopTimer];
}
}
TIMER_SERVICE_UNLOCK(self.operationsLock)
}
使用
需要接收定時器回調的模塊,只要實現(xiàn)TimerListener協(xié)議,在需要接收定時器回調的時把其添加到TimerService中,在業(yè)務不需要接收定時器回調的時候把其從TimerService中移除即可,這樣所有的倒計時業(yè)務只需要維護一個定時器即可搞定。
其他
當然要很好的搞定一個倒計時還需要解決其他一些問題,比如客戶端時間校準問題,關于這個問題推薦細細讀一下MrPeak君的一篇文章《iOS關于時間的處理》。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
iOS中UIActivityIndicatorView的用法及齒輪等待動畫實例
UIActivityIndicatorView活動指示器最常見的用法便是用來制作那個程序中的齒輪轉動的等待效果,接下來我們回來簡單整理iOS中UIActivityIndicatorView的用法及齒輪等待動畫實例:2016-05-05

