欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解iOS中多倒計(jì)時(shí)場(chǎng)景的解決方案

 更新時(shí)間:2018年11月22日 09:33:36   作者:小莫醬  
在我們開發(fā)APP的過(guò)程中,或多或少都遇到過(guò)需要使用倒計(jì)時(shí)的場(chǎng)景,這篇文章主要介紹了詳解iOS中多倒計(jì)時(shí)場(chǎng)景的解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

背景

在我們開發(fā)APP的過(guò)程中,或多或少都遇到過(guò)需要使用倒計(jì)時(shí)的場(chǎng)景,大多數(shù)應(yīng)用中的用戶登錄注冊(cè)過(guò)程中獲取驗(yàn)證碼的倒計(jì)時(shí),電商或者外賣APP中的訂單送達(dá)的倒計(jì)時(shí),以及秒殺類APP的秒殺倒計(jì)時(shí)等。對(duì)于這些需要倒計(jì)時(shí)的場(chǎng)景,通常情況下的解決方案是:在需要展示倒計(jì)時(shí)的各View模塊各自維護(hù)一個(gè)自己的倒計(jì)時(shí)Timer,通過(guò)Timer的回調(diào)和模塊本身需要的倒計(jì)時(shí)時(shí)間來(lái)更新對(duì)應(yīng)View的倒計(jì)時(shí)的顯示,再在此基礎(chǔ)上加上對(duì)應(yīng)的時(shí)間校準(zhǔn)方案,一個(gè)簡(jiǎn)單的倒計(jì)時(shí)需求就完成了。

問(wèn)題

對(duì)于APP內(nèi)倒計(jì)時(shí)的業(yè)務(wù)如果只出現(xiàn)在單一的頁(yè)面或者是少數(shù)的頁(yè)面場(chǎng)景中沒什么太大的問(wèn)題的,通常對(duì)于秒殺類APP的倒計(jì)時(shí)場(chǎng)景往往是在某個(gè)頁(yè)面或者某幾個(gè)頁(yè)面中有多個(gè)倒計(jì)時(shí)共同存在的,這種產(chǎn)品需求的技術(shù)展現(xiàn)方式可能是TableView或者CollectionView中的多個(gè)Cell,也可能是多個(gè)自定義的View模塊,如果我們此時(shí)依然使用每個(gè)Cell或者每個(gè)View模塊各自維護(hù)一個(gè)單獨(dú)的倒計(jì)時(shí)Timer,當(dāng)前APP內(nèi)就會(huì)同時(shí)存在多個(gè)定時(shí)器Timer,這對(duì)于性能來(lái)說(shuō)是存在一定程度的影響的。那么我們?cè)趺床拍芨玫慕鉀Q多倒計(jì)時(shí)場(chǎng)景的問(wèn)題呢?

解決方案

既然我們不能讓每一個(gè)顯示倒計(jì)時(shí)的View模塊各自維護(hù)一個(gè)定時(shí)器Timer,那我們就提供一個(gè)專門的模塊TimerService來(lái)提供倒計(jì)時(shí)的服務(wù),TimerService內(nèi)部負(fù)責(zé)維護(hù)唯一一個(gè)定時(shí)器,同時(shí)提供添加和移除監(jiān)聽者的接口以及監(jiān)聽者需要實(shí)現(xiàn)的協(xié)議protocol,內(nèi)部通過(guò)HashTable來(lái)存儲(chǔ)監(jiān)聽者,每次定時(shí)器回調(diào),遍歷所有監(jiān)聽者進(jìn)行回調(diào),監(jiān)聽者在不需要接收定時(shí)器回調(diào)的時(shí)候只需要從TimerService中移除即可。

TimerService.h對(duì)外提供的API和監(jiān)聽者需要實(shí)現(xiàn)的協(xié)議主要如下:

//監(jiān)聽者需要實(shí)現(xiàn)的協(xié)議
@protocol TimerListener <NSObject>
@required
- (void)didOnTimer:(TimerService *)timer;
@end

//對(duì)接提供的主要接口
+ (instancetype)sharedInstance;
- (void)addListener:(id<TimerListener>)listener;
- (void)removeListener:(id<TimerListener>)listener;

TimerService.m的內(nèi)部主要實(shí)現(xiàn)如下:


//定時(shí)器回調(diào)
- (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){  
  //啟動(dòng)  
  [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)
}

使用

需要接收定時(shí)器回調(diào)的模塊,只要實(shí)現(xiàn)TimerListener協(xié)議,在需要接收定時(shí)器回調(diào)的時(shí)把其添加到TimerService中,在業(yè)務(wù)不需要接收定時(shí)器回調(diào)的時(shí)候把其從TimerService中移除即可,這樣所有的倒計(jì)時(shí)業(yè)務(wù)只需要維護(hù)一個(gè)定時(shí)器即可搞定。

其他

當(dāng)然要很好的搞定一個(gè)倒計(jì)時(shí)還需要解決其他一些問(wèn)題,比如客戶端時(shí)間校準(zhǔn)問(wèn)題,關(guān)于這個(gè)問(wèn)題推薦細(xì)細(xì)讀一下MrPeak君的一篇文章《iOS關(guān)于時(shí)間的處理》。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論