原址 http://www.cnblogs.com/zhangmaliang/p/5102518.html

  最近项目中用到了tableView的多个cell倒计时系统问题,本觉得很简单的一个事,一做发现还没这么简单,就此记录。

  下面方法模拟网络请求返回数据。

  按照常规思路,根据网络请求返回remainTime,封装模型,存到数组中,再在表格代理方法中赋值给cell

  cell中根据传入模型中的remainTime属性,开启定时器每隔1s调用如下方法

  程序一运行发现问题:每当表格滚动时,表格代理方法cellForRowAtIndexPath会不断重复调用,从数组中取得模型赋值给cell,而模型中的remainTime是固定的,于是倒计时系统不断重复开始倒计时。

​  发现问题点,开始着手解决。开始想到的是方法是在控制器中也开启一套定时器系统,当服务器数据remainTime返回时,将其中remainTime大于0s的数据保存在一个字典中,对所有键值对开始倒计时。

  下面方法模拟网络数据返回,对所有remainTime大于0的字段保存到字典self.timerDic中

  控制器中,定时器每隔1s调用方法,对remainTime减一后再覆盖掉原本键值对
 
 
 
  于是,字典self.timerDi中所有键值对的value每隔1s递减1,直到最后value都变为0。在cellForRowAtIndexPath方法中插入如下
 
 

  cell属性model中的remainTime字段从这个一直变化的self.timerDic字典中取值,于是滚动视图时cell获取到的就不是一个固定的remainTime,效果如下

​​

​  此时已经解决了表格滚动时倒计时重复计时问题,但可以看到多次滚动后会造成如上显示错误,这是由于控制器和cell两套定时系统时差而引起的,具体后面分析。

  此路貌似不通,于是我想到了KVO,让cell监听控制器中remainTime的数值变化​

 这方法还真走效,在cell的observeValueForKeyPath中确实能监听到remainTime的数值变化,数值也异常正确,但同时一个重大问题也产生了,由于cell的复用,cell上所显示的倒计时系统相互错乱,试了几种方法都无法解决,放弃。
 

  仔细分析上面倒计时时差原因,发现时差产生是由于定时器调用频率导致。举个场景说明:控制器返回数据时remainTime是10,过了0.9999s后用户滚动表格,此时cell从字典self.timerDic中取到的remainTime仍旧是10,于是cell定时系统的remainTime值比控制器的慢了0.9999s。同理分析也可能快0.9999s,于是可能会引发最多2s的极限误差。

  找到具体原因修改就比较容易了,使用CADisplayLink,一分钟调用60次countDown方法,每次减去1/60s,则最大误差只有2*1/60s,比较准确,能够满足要求

  最后做下适当优化:定时器在主线程工作,调用频率很高,每次调用还要遍历字典对每一个value递减后覆盖旧值,故希望定时器能在后台工作。定时器工作在后台线程时会自动将其注册到后台线程的runloop,而runloop依托线程但并不会自动创建,此时countDown无法接收到事件回调,需要手动生成runloop并保证其不会退出。这里参照AFN中的生成方法,核心代码如下:

 
  刚开始学swift,因工作还在用OC,只能平时练练手了,:上代码为swift版
  github地址:https://github.com/zhangmaliang/CountDown

cell上添加倒计时,以及时差问题的解决的更多相关文章

  1. iOS tableview自定义cell上添加按钮实现删除功能

    在删除的时候,先删除数据源,再删除cell 但是,会发现一直崩: numberOfRowsInSection 解决方案:

  2. iOS: 获取UITableViewCell上添加的子控件对应的cell

    一.简单介绍 UITableViewCell是UITableView的核心部分,我们在开发中因为功能的扩展经常需要自定义,以便在其上面添加子控件,例如button.label等.添加后获取这些子控件的 ...

  3. ios 添加到cell 上的button点击无效!扩大button的点击区域(黑魔法)

    一般情况下点击效果都是正常的!要不然你对它做了什么?一般细心的小伙伴都没有遇到这种情况,但是呢! 当然我是二班的!在这里我主要讲两个问题,解决问题和普及魔法. 一.普及问题(button在cell上点 ...

  4. iOS 在cell中使用倒计时的处理方法(新)

    一.前言 之前的文章iOS 在cell中使用倒计时的处理方法得到大量的支持, 在这先感谢大家的支持. 但是也收到不少人的回复表示不会用, 需要一一解答, 由于之前写的时候没有使用Markdown编辑, ...

  5. iOS 在tableView上添加button导致按钮没有点击效果和不能滑动的 zhuang

    转载请注明出处. 今天在调试代码的时候,在tableviewcell上添加button,发现button快速点击的话,是看不出点击效果的,查找资料发现, ios7上UITableViewCell子层容 ...

  6. iOS回顾笔记(09) -- Cell的添加、删除、更新、批量操作

    iOS回顾笔记(09) -- Cell的添加.删除.更新.批量操作 项目中经常有对UITableViewCell做各种操作的需求: 添加一个新的cell 删除某行cell 刷新cell上某行数据(如修 ...

  7. iOS实现类似QQ的好友列表,自由展开折叠(在原来TableView的基础上添加一个字典,一个Button)

    //直接代码 只包含 折叠展开字典的处理搭建#import "CFViewController.h" @interface CFViewController ()<UITab ...

  8. iOS:在cell中使用倒计时的最佳方法

    一.简单介绍 在UITableViewCell中每条数据中显示该内容的倒计时, 并随时间进行倒数,这是很多电商app最常见的活动推销功能模块,自然想到用的就是计时器了. 二.基本想法 想法1:在每个c ...

  9. cell上的按钮点击和左滑冲突

    cell上的某个按钮的点击事件,当cell左滑的时候,只要活动的区域也在按钮上,那么按钮的点击事件也会调用. fix: 给按钮添加一个手势(TapGesture)那么当点击的时候就会响应点击手势的方法 ...

随机推荐

  1. 基于vue,打印机打印暂且处理

    基于vue单页面应用.暂且没找到合适的方案,什么vue-print  .jquery.print.js.jqprint.js..canvas生成图片啊 大多不能保证页面样式保持原样. 所以,选择了最土 ...

  2. 重启mysql主从同步mongodb(tungsten-replicator)

    1. 连接mysql mysql -uroot -p;(mysql从库) 输入数据库密码 2. 停止主同步 mysql> stop slave; 3. 清数据 将mongo库数据清空 4. 杀主 ...

  3. ssh密钥登录

    一.生成密钥对(两种方式)并配置 方式1:使用ssh-keygen(1)生成并配置 (1)生成密钥对 [root@iZwz9catu2mrq92b07d1d0Z ~]# ssh-keygen -t r ...

  4. fragment显示 Binary XML file line #12: Error inflating class fragment 错误

    问题 最近换了新机子,今天在静态用fragment时突然发现闪退,一看显示 Binary XML file line #12: Error inflating class fragment 错误 后面 ...

  5. ShoneSharp语言(S#)的设计和使用介绍系列(3)— 修炼工具

    ShoneSharp语言(S#)的设计和使用介绍 系列(3)- 修炼工具 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...

  6. CNN网络介绍与实践:王者荣耀英雄图片识别

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者介绍:高成才,腾讯Android开发工程师,2016.4月校招加入腾讯,主要负责企鹅电竞推流SDK.企鹅电竞APP的功能开发和技术优化工作 ...

  7. codeforces 630C - Lucky Numbers 递推思路

    630C - Lucky Numbers 题目大意: 给定数字位数,且这个数字只能由7和8组成,问有多少种组合的可能性 思路: 假设为1位,只有7和8:两位的时候,除了77,78,87,88之外还哇哦 ...

  8. Etcd全套安装教程

    一.安装 1.1 二进制安装 从这里下载: etcd-v3.2.11-linux-amd64.tar.gz 下载包后解压即可运行: # 解压 tar zxvf etcd-v3.2.11-linux-a ...

  9. UWP 图片缩放

    给Image外面包裹一个ScrollViewer,你会回来感激我的. 哦,对了,PC上需要按住Ctrl键,滑动鼠标滑轮即可:手机上双指就可以缩放. <ScrollViewer ZoomMode= ...

  10. Linux正则表达式语法

    基本组成部分: 正则表达式的基本组成部分. 正则表达式 描述 示例 \ 转义符,将特殊字符进行转义,忽略其特殊意义 a\.b匹配a.b,但不能匹配ajb,.被转义为特殊意义 ^ 匹配行首,awk中,^ ...