当socket连接主推数据刷新频繁造成UI界面卡顿的一些思考(限流)

问题原因是有个点差列表的界面,前期是自己socket工具封装自己代码的失误,造成数据源data不断追加,比较专业的行情数据,都会定义规范的结构体,会返回当前数据包的长度,次数在于数据处理时可以处理一部分抛除一部分,但是本人实际项目中只是简单地返回的字符串的data数据,这样就算socket断包,我们也不方便处理,所以就简单地每次只处理接受的数据,(更合理的应该是用nsmutabledata不断的追加拼接数据,然后解包根据包头返回的实际内容的长度截取处理)

然后由于此列表 (交易商数*对应的交易品种)比较多,从而造成数据变化特别频繁,从而造成刷新列表的卡顿

主要修改的几个地方:
1.主推频繁,然后每次主推里边有循环处理数据,所以此处将数据处理放在了子线程中,数据处理好之后用代理或者block返回时拉回主线程

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
//    LOG(@".net行情数据~~~~~");
//    if(self.socketData == nil){
//        self.socketData = [[NSData alloc] init];
//    }
    
    NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if ([dataStr containsString:@"Heart"]) {
//        LOG(@"心跳正常");
    }else{
        
//        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//        LOG(@"~~~点差数据:%@",str);
        self.socketData = [NSData dataWithData:data];
    }
    
    //常用方式异步并发+与主线程交互
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //耗时长的操作
        [self dealWithSocketData];//处理数据
        [self.socket readDataWithTimeout:10 tag:tag];
    });
}

-(void)dealWithSocketData{
    
    if (![_socketData isKindOfClass:[NSData class]]) {
        return;
    }
    if (_socketData.length > 2) {
        
        NSString *dataStr = [[NSString alloc] initWithData:self.socketData encoding:NSUTF8StringEncoding];
        NSArray *strArr = [dataStr componentsSeparatedByString:@"#"];
        
        NSMutableArray *strMarry = [NSMutableArray arrayWithArray:strArr];
        [strMarry removeLastObject];
        NSString *str = strArr[0];
        NSString *typeStr = @"";
        if (str.length > 2) {
            typeStr = [str substringToIndex:2];
        }
        if (![typeStr isEqualToString:@"01"] && ![typeStr isEqualToString:@"02"]) {
            [strMarry removeObjectAtIndex:0];
        }
        
        str = strMarry[0];
        typeStr = [str substringToIndex:2];
        strArr = [NSArray arrayWithArray:strMarry];
        
        if ([typeStr isEqualToString:@"01"]) {
            //数据格式 点差    点差类型(01),交易商Code,品名,点差
            //               01,000001674566,EURUSD,2.0
            
            NSMutableArray *xlSocketModelMArr = [NSMutableArray arrayWithCapacity:1];
            
            for (NSString *singleStr in strArr) {
                if (singleStr.length > 0) {
                    NSArray *valuesArr = [singleStr componentsSeparatedByString:@","];
                    NSString *type = valuesArr[0];
                    if ([type isEqualToString:@"01"]) {
                        
                        XLSocketModel *model = [XLSocketModel new];
                        
                        if (valuesArr.count > 2) {
                            model.n = valuesArr[2];
                        }
                        //此处修改逻辑 2017.12.14 只要符合的三个点差
                        if ([model.n isEqualToString:@"EURUSD"] || [model.n isEqualToString:@"XAUUSD"] || [model.n isEqualToString:@"OILUSD"]) {
                            if (valuesArr.count > 1) {
                                model.traderCode = valuesArr[1];
                            }
                            if (valuesArr.count > 3) {
                                model.spread = valuesArr[3];
                            }
                            [xlSocketModelMArr addObject:model];
//                             LOG(@"~~~点差数据:%li~~",xlSocketModelMArr.count);
                        }else{
                            continue;
                        }
                    }
                }
            }

            dispatch_async(dispatch_get_main_queue(), ^{
                //主线程界面刷新
                if (self.allTraderSpreadDataBlock) {
                    self.allTraderSpreadDataBlock(xlSocketModelMArr);
                }
                if (self.singleTraderCodeSpreadDataBlock) {
                    self.singleTraderCodeSpreadDataBlock(xlSocketModelMArr);
                }
            });
            
        }else if ([typeStr isEqualToString:@"02"]){
         
            //数据格式 行情    行情类型(02),交易商Code,品名,买入价,卖出价,点差
            //               02,000001674566,EURUSD,2.1345,3.12344,28
            NSMutableArray *xlSocketModelMArr = [NSMutableArray arrayWithCapacity:1];
            for (NSString *singleStr in strArr) {
                if (singleStr.length > 0) {
                    NSArray *valuesArr = [singleStr componentsSeparatedByString:@","];
                    NSString *type = valuesArr[0];
                    if ([type isEqualToString:@"02"]) {
                        
                        XLSocketModel *model = [XLSocketModel new];
                        model.traderCode = valuesArr[1];
                        model.n = valuesArr[2];
                        model.bid = valuesArr[3];
                        model.sel = valuesArr[4];
                        model.spread = valuesArr[5];
                        [xlSocketModelMArr addObject:model];
                    }
                }
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                //主线程界面刷新
                if (self.singleTraderMarketDataBlock) {
                    self.singleTraderMarketDataBlock(xlSocketModelMArr);
                }
            });
            
        }
    }
    
}

2.限制刷新频率+只刷新界面上的cell

(1) kPreventRepeatClickTime(0.5);//限制刷新频率,引起卡顿的问题是刷新频率太快,此处硬代码处理

// 防止多次调用
#define kPreventRepeatClickTime(_seconds_) \
static BOOL shouldPrevent; \
if (shouldPrevent) return; \
shouldPrevent = YES; \
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((_seconds_) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ \
shouldPrevent = NO; \
}); \

(2)MessageThrottle,限流控制刷新频率,参考https://www.jianshu.com/p/5dacd8778a5a

-(void)reloadTableViewData{

//(1.)限制刷新频率,引起卡顿的问题是刷新频率太快,此处硬代码处理    
  kPreventRepeatClickTime(0.5);

//(2.)限制刷新的频率 xinle
        [self mt_limitSelector:@selector(tableViewReloadData) oncePerDuration:(0.10)];
    
    if (_isAllowRefresh) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSArray *cells = [self.tableView indexPathsForVisibleRows];//取出当前界面上的cell
            if (cells.count > 0 && self.dataArr.count > 0 && self.dataArr.count >= cells.count) {
                //主线程界面刷新
                [self.tableView reloadRowsAtIndexPaths:cells withRowAnimation:(UITableViewRowAnimationNone)];
//                 LOG(@"~~~reloadRowsAtIndexPaths~~~");
            }
        });
    }
}

3.设置开关,当列表拖动的时候不刷新

//开始拖动时禁止刷新
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    if ([scrollView class] == [self.tableView class]) {
        self.isAllowRefresh = 0;
    }
}
//减速完毕
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if ([scrollView class] == [self.tableView class]) {
        self.isAllowRefresh = 1;
    }
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if ([scrollView class] == [self.tableView class]) {
        if (!decelerate) {
            self.isAllowRefresh = 1;
        }
        [self getAllTraderSPread];
    }
}

tableview刷新可以考虑cell通知监听单刷,不用整个tableview整体刷新

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

推荐阅读更多精彩内容