美文网首页
当socket连接主推数据刷新频繁造成UI界面卡顿的一些思考

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

作者: 辛乐 | 来源:发表于2018-08-16 16:58 被阅读268次

    问题原因是有个点差列表的界面,前期是自己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

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

    -(void)reloadTableViewData{
        
        kPreventRepeatClickTime(0.5);//限制刷新频率,引起卡顿的问题是刷新频率太快,此处硬代码处理
        
        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];
        }
    }
    

    相关文章

      网友评论

          本文标题:当socket连接主推数据刷新频繁造成UI界面卡顿的一些思考

          本文链接:https://www.haomeiwen.com/subject/lfeobftx.html