iOS,cell中有倒计时情况的总结

一.先去网上探索

自己的项目中用到了关于倒计时的功能,请求的列表数据中有些cell是需要显示倒计时的, 之前没有做过这个功能, 以为应该一会儿就搞定了。 事实 上也是一会儿就搞个倒计时的效果出来了,感觉自己萌萌哒, 也就不去管了,可是过了几天测试数据的时候发现了很严重的cell重用问题,倒计时数据会出现错乱。于是开始在网上搜索解决方案,总结了一下大概是这样实现:
  
  遍历请求到的数据源,然后开启定时器,每过一秒就遍历所有数据源,然后把里面的数据更改之后再重新赋值回去。

显而易见,每过一秒就遍历所有的数据源去自减数据很耗性能,而且我的项目中,并不是每个cell里都有倒计时,不需要做这么多多余的操作。

而且,我按照其中一种方法写的结果,虽然可以防止重用cell带来的数据混乱,但是快速滚动tableView的时候停下来之后,cell上的数据会有短暂的不对(就是上一个cell的倒计时数据)一秒之后才会变成正确的数据,另一方面定时器的销毁也成了问题,销毁之后全部cell都失去倒计时的功能,完全不符合需求。

二. 结合网上的示例自己的解决方案

基于上面的缺陷,我想到了一个方法可以保证性能消耗不那么大,而且数据也不会出现错乱。而且包括数据的请求,缓存本地,上拉加载和上拉刷新时候带来的倒计时问题。具体源代码可以去github上下载,其实都是很简单的实现方法只是可能之前没有人分享出来,如果你发现代码中的 bug,或者你有更好的方法,欢迎批评指正!
  这里写出核心的思想。如果你的项目和我一样有这些需求,那么可以给你作一个参考。

  • timer 的添加和销毁


    timer.gif
  • 数据不会重用

mix.gif

控制器中的代码

  • 首先遍历数据源,取出需要倒计时的数据模型
-(void)enumerateDatasourceCountDown
{
    for(int i = 0; i < self.dataSource.count; ++i)
    {
        DataModel *model = self.dataSource[i];
        if (model.countTime)
        {
            [self countDownModel:model andIndexPath:i];
        }
    }
}
  • 把倒计时的具体剩余时间和与之对应的indexPath保存起来在字典中
-(void)countDownModel:(DataModel *)model andIndexPath:(NSInteger )indexInteger
{
    //哪一行的数据有倒计时
    NSString *indexKey = [NSString stringWithFormat:@"%ld",indexInteger];
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:indexKey forKey:@"indexPath"];
    [dict setObject:@(model.countTime) forKey:indexKey];
    
    //把模型里的倒计时储存在字典中 以行数index索引为key
    //添加定时器之前先判断这一行的数据是不是已经添加了定时器
    NSNumber *number = self.countDownTimeDict[indexKey];
    NSInteger numberInteger =  [number integerValue];
    
    //如果在倒计时的字典中取不到 value 说明还没有添加定时器
    if (numberInteger <= 0)
    {
        //添加定时器
        NSTimer *timer  =  [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(numberCutDown:) userInfo:dict repeats:YES];
        [self.timerArr addObject:timer];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        
        NSLog(@"第%ld行已经添加了定时器",indexInteger);
    }
    [self.countDownTimeDict addEntriesFromDictionary:dict];

  • 定时器会执行的方法 (在这个方法中修改模型的倒计时,因为模型决定了cell显示什么数据,所以更改模型之后再去刷新这一行就不会出现数据混乱)
-(void)numberCutDown:(NSTimer *)timer
{
    //取出对应倒计时
    NSString * indexInteger = timer.userInfo[@"indexPath"];
    NSInteger index = [indexInteger integerValue];
    
    DataModel *model = self.dataSource[index];
    //修改模型时间
    model.countTime --;
    //刷新界面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
    if (model.countTime == 0)
    {
        NSLog(@"第%ld行的定时器销毁了",index);
        [timer invalidate];
        timer = nil;
        return;
    }
}

总结:

这种方式,是在控制器中每过一秒就修改数据源,然后再重新刷新这一行数据达到倒计时的效果,解决了上述的两个问题。

  • 在控制器中创建timer定时器,一个定时器管理一个cell,如果cell的倒计时结束了,那就停止定时器,而且不会影响到其他cell,也不会浪费性能。
  • 由于修改的是模型,所以避免了数据混乱。
  • 本文 Demo
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容