zoukankan      html  css  js  c++  java
  • [每天记录一个Bug]Cell中由于block加载网络请求产生的复用

    Bug 出现场景:
     
    cell中使用加载图片的网络请求出现复用,截图如下:
     
     
     EF80175E C0E5 4F8F 8DE5 02087BCB8E68
     
    复用原因:
     
    Cell Model中只有一个用户的uid,所有用户相关信息:例如头像名称信息等是通过 block请求,通过uid 回调中取到的字段,但由于是在cell中通过系统的block回调中下载得到的头像,所以会有延时问题.
     
    当使用 self.collection reloadData ,这个语句的时候,由于4个cell的头像还没加载成功,瞬间又重新复用4个cell出来,就会产生复用的情况。
     
    也就是说  4个cell地址如下:
     
    0XA1
    0XA2
    0XA3
    0XA4 
     
    4个cell地址正序排列,分别取block请求拉取头像的时候,此时还没有拉取成功,瞬间执行语句  self.collection reloadData。cell 会产生复用机制,地址排列顺序如下:
     
    0XA4 
    0XA3
    0XA2
    0XA1
     
    此时就会产生复用,由于第一个cell网络请求较快,但是第4个cell请求比较慢,就会产生复用:
     
    因为
     
    0XA1 头像加载成功
    0XA2
    0XA3
    0XA4 头像未加载成功
     
    reloadData后复用
     
    0XA4 头像加载成功,但是由于复用之前block还没有加载成功,导致在之前cell中的0XA4的头像直接覆盖了,复用后的0XA4的头像。
    0XA3
    0XA2
    0XA1 由于复用钱0XA1头像加载速度较快,所以这个cell不会出现复用情况。适合网络加载快慢相关
     
    cell中使用block进行网络请求,就容易出现此问题。
     
    即时在 cell中的 prepareReuse()方法中将cell置nil,也会出现复用问题,因为根本原因是在block块中出现的复用问题。
     
    解决方案:
     
    在 block 块中 ,记录回调前的 user.uid 数据,然后和 cell此时记录的变量 model.uid 进行对比,因为model.uid是cell自带的字段,不会被复用的字段,而block中的user.uid是block回调后的字段,可能是之前cell中保留的字段。
    进行对比,就知道block是复用前的,还是复用后的。
     
    block里的变量不会变,但是复用后的cell Model会变。
     
    解决方案 :
     
    user.uid block回调产生的用户字段,_chatModel.chatCreater 是Model中的字段,不会被block所截取的临时变量。
     
    if ([_chatModel.chatCreaterisEqualToString:user.uid]) {
        //没被复用
    }
    else {
        //被复用
    }
     
     
    代码如下:
     
            IDSLOG(@"Home msg. model.chatCreater: %@,cell:%@", model.chatCreater,self);
            @weakify(self);
     
            [[IDSUserCachesharedCache] findUser:model.chatCreatercallback:^(NSArray<IDSLoginUser *> *users) {
                @strongify(self);
               
                if (IS_NS_COLLECTION_EMPTY(users)) {
                    return;
                }
                IDSLoginUser *user = [users cl_objectAtIndex:0];
                IDSLOG(@"_chatModel.chatCreater : %@, user.uid:%@, model.chatCreater:%@", _chatModel.chatCreater, user.uid, model.chatCreater);
                if ([_chatModel.chatCreaterisEqualToString:user.uid]) {
                    NSURL *bgimageUrl = nil;
                    if (!IS_NS_STRING_EMPTY(user.avatar_url)){
                        bgimageUrl = [AppUtilurlEncodeToNSURL:user.avatar_url];
                    }
                   
                    staticUIImage *defImg;
                    staticdispatch_once_t onceToken;
                    dispatch_once(&onceToken, ^{
                        defImg = [[IDSImageManagersharedManager] defaultAvatar:CircleStyle];
                    });
                    [self.avatarImageViewsd_setImageWithURL:bgimageUrl
                                            placeholderImage:defImg
                                                     options:SDWebImageRetryFailed|SDWebImageLowPriority];
                   
                    self.nameLabel.text = user.username;
                    self.nameLabel.frame = CGRectMake(CGRectGetMaxX(self.avatarImageView.frame)+7,
                                                      CGRectGetMinY(self.chatLabel.frame)-7-self.nameLabel.contentSize.height, 0, 0);
                    self.avatarImageView.layer.cornerRadius = self.avatarImageView.frame.size.width/2.0;
                    [self.nameLabelsizeToFit];
                   
                    self.timeLabel.frame = CGRectMake(CGRectGetMaxX(self.nameLabel.frame)+5, 0, 0, 0);
                    self.timeLabel.text = [TimeUtilcl_prettyDateWithReference:_chatModel.timestamp];
                    [self.timeLabelsizeToFit];
                    self.timeLabel.centerY = self.nameLabel.centerY;
                }
            }];
  • 相关阅读:
    stl rope
    vijos1574 摇钱树
    图论 Dijkstra+堆优化
    c++输入优化
    Vijos1579 宿命的PSS 最小生成树
    快速求n阶多项式乘积
    c++stl map
    C#函数式程序设计之惰性列表工具——迭代器
    C#函数式程序设计之泛型(下)
    C#函数式程序设计之泛型(上)
  • 原文地址:https://www.cnblogs.com/firstrate/p/8042486.html
Copyright © 2011-2022 走看看