多個cell中展示倒數計時,本地和伺服器時間差異解決方案
公司需要做限時搶購的業務,這裡面有兩個需求點:
1.在多個cell中顯示倒數計時
在每個cell中新增定時器是不現實的,必定會增加許多效能開銷,所以肯定是使用一個定時器,關鍵在於如何通知到cell重新整理UI
2.本地時間可能和伺服器時間存在誤差
有的手機可能時間沒有和網路同步,或者使用者故意調整了時間,所以本地時間存在錯誤的可能,所以就定下使用伺服器時間
1.在多個cell中顯示倒數計時
思路是這樣的:將需要接收定時器通知的物件註冊到定時器單例中,存放在陣列裡面,當定時器更新的時候遍歷陣列回撥通知
定時器的建立
注意:預設暫停定時器,定時器預設是載入到當前runloop中的,在進行UI介面操作比如滑動列表時,由於在main runloop中NSTimer是同步交付的被“阻塞”,就會導致NSTimer計時出現延誤。
解決這種延誤的方法,一種是在子執行緒中進行NSTimer的操作,在主執行緒中修改UI介面顯示操作結果;另一種是仍然在主執行緒中進行NSTimer操作,但是將NSTimer例項加到main runloop的特定mode(模式)中。避免被複雜運算操作或者UI介面重新整理所干擾。
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: {[unowned self] (_) in
self.onTimer()
})
//下面這種方法要求onTimer是@objc
//Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(onTimer), userInfo: nil, repeats: true)
註冊通知
這裡使用NSHashTable存放註冊物件的陣列,可以防止迴圈引用註冊物件釋放不掉
swift的protocol是一個很好的東西,這樣可以更好的規範誰可以註冊通知
@objc
protocol TimerListener: class {
func didOnTimer(announcer: YZTimerUtil, timeInterval: TimeInterval)
}
private let map: NSHashTable<TimerListener> = NSHashTable<TimerListener>.weakObjects()
何時註冊刪除通知
一開始是在willDisplay、didEndDisplaying方法中進行通知註冊的,後來發現沒有必要,因為cell建立後就是要接收通知的willDisplay、didEndDisplaying中還要進行cell型別的判斷,所以就改為cell- init/deinit中
deinit {
YZTimerUtil.sharedInstance.removeListener(listener: self)
}
//這裡cell使用的是xib
override func awakeFromNib() {
super.awakeFromNib()
YZTimerUtil.sharedInstance.addListener(listener: self)
}
2.本地時間可能和伺服器時間存在誤差
這裡看專案需求吧,如果專案對時間要求沒有那麼嚴格,不做伺服器時間對比也行,反正伺服器那邊會進行判斷的,有些對時間要求嚴格的肯定是要做對比的,比如手機手令的動態碼
我的思路是在定時器初始化的時候進行網路請求,拿到伺服器的當前時間,然後計算本地和伺服器時間的差值,後面就用這個差值進行計算。當然,受網路狀態的影響,這個時間可能也不是準確的時間,但是這個時間誤差會在一個可控範圍內,為了精確時間差,可以每隔一段時間就校準一次,如果要更精準的,可以通過請求的requestTime/responseTime進行演算法計算
// 從伺服器請求最新的時間,簡單示例
func resetServerTime() {
// 從伺服器請求最新的時間
// ...
var success = true
if success {
// 請求成功
serverTimeInterval = 0
} else {
// 如果請求失敗,隔一段時間再請求一次
perform(#selector(resetServerTime), with: nil, afterDelay: rloadTimeInterval)
}
}
相關文章
- 計算時間差,頁面倒數計時,安卓與ios相容問題安卓iOS
- iOS倒數計時設計思路和一個系統時間的坑iOS
- js實現指定時間倒數計時JS
- 簡單實現時間倒數計時與伺服器同步效果伺服器
- js 計算兩個時間的時間差JS
- 計算兩個時間差
- 線上直播系統原始碼,預設倒數計時,自定義輸入時間倒數計時原始碼
- 倒數計時快取時間問題總結快取
- Android中handler倒數計時Android
- JavaScript計算兩個時間點之間的時間差JavaScript
- jQuery 倒數計時效果詳解jQuery
- js 活動倒數計時詳解JS
- JavaScript計算時間差詳解JavaScript
- 解決MongoDB儲存時間時差的問題MongoDB
- JavaScript倒數計時JavaScript
- js——倒數計時JS
- JS倒數計時JS
- 解決java獲取系統時間差8個小時 專題Java
- 倒數計時一定時間跳轉到另一個頁面
- 時間差計算
- Perl中本地時間和UNIX時間戳間相互轉換時間戳
- oracle計算兩個日期的時間差時分秒Oracle
- mysql時間操作(時間差和時間戳和時間字串的互轉)MySql時間戳字串
- NTP時間同步伺服器(區域網時鐘同步)解決方案伺服器
- JavaScript 天小時分鐘和秒倒數計時JavaScript
- javascript小時、分鐘和秒倒數計時效果JavaScript
- cell (iOS表格) - 簡單實現一個定時器管理600個倒數計時 - 2.程式碼介紹篇iOS定時器
- 直播小程式原始碼,vue實現時間倒數計時原始碼Vue
- 內網外網伺服器時間同步解決方案內網伺服器
- C#中計算兩個時間的差,得到月份C#
- Kookjs 倒數計時JS
- 倒數計時34天
- JS計算時間差JS
- iOS 時間校準解決方案iOS
- java計算時間差及比較時間Java
- 計算兩段時間的時間差 (轉)
- 倒數計時指定時間頁面跳轉程式碼例項
- 用Excel做個工程倒數計時牌Excel