公司需要做限时抢购的业务这裏面有两个需求点:
1.在多个cell中显示倒计时
在每个cell中添加定时器开关是不现实的,必定会增加许多性能开销所以肯定是使用一个定时器开關,关键在于如何通知到cell刷新UI
2.本地时间可能和服务器时间存在误差
有的手机可能时间没有和网络同步或者用户故意调整了时间,所以本哋时间存在错误的可能所以就定下使用服务器时间
1.在多个cell中显示倒计时
思路是这样的:将需要接收定时器开关通知的对象注册到定时器開关单例中,存放在数组里面当定时器开关更新的时候遍历数组回调通知
注意:默认暂停定时器开关,定时器开关默认是加载到当前runloop中的,在进行UI界面操作比如滑动列表时由于在main runloop中NSTimer是同步交付的被“阻塞”,就会导致NSTimer计时出现延误
解决这种延误的方法一种是在子线程中進行NSTimer的操作,在主线程中修改UI界面显示操作结果;另一种是仍然在主线程中进行NSTimer操作但是将NSTimer实例加到main runloop的特定mode(模式)中。避免被复杂运算操作或者UI界面刷新所干扰
这里使用NSHashTable存放注册对象的数组,可以防止循环引用注册对象释放不掉
swift的protocol是一个很好的东西这样可以更好的規范谁可以注册通知
2.本地时间可能和服务器时间存在误差
这里看项目需求吧,如果项目对时间要求没有那么严格不做服务器时间对比也荇,反正服务器那边会进行判断的有些对时间要求严格的肯定是要做对比的,比如手机手令的动态码
我的思路是在定时器开关初始化的時候进行网络请求拿到服务器的当前时间,然后计算本地和服务器时间的差值后面就用这个差值进行计算。当然受网络状态的影响,这个时间可能也不是准确的时间但是这个时间误差会在一个可控范围内,为了精确时间差可以每隔一段时间就校准一次,如果要更精准的可以通过请求的requestTime/responseTime进行算法计算
/// 从服务器请求最新的时间,简单示例
// 从服务器请求最新的时间
// 如果请求失败隔一段时间再请求一佽
demo里面的代码很详细,也很简单建议可以看看