[每天记录一个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 . chatCreater isEqualToString :user. uid ]) {
    //没被复用
}
else {
    //被复用
}
 
 
代码如下:
 
          IDSLOG ( @"Home msg. model.chatCreater: %@,cell:%@" , model. chatCreater , self );
        @ weakify ( self );
 
        [[ IDSUserCache sharedCache ] findUser :model. chatCreater callback :^( 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 . chatCreater isEqualToString :user. uid ]) {
                NSURL *bgimageUrl = nil ;
                if (! IS_NS_STRING_EMPTY (user. avatar_url )){
                    bgimageUrl = [ AppUtil urlEncodeToNSURL :user. avatar_url ];
                }
               
                static UIImage *defImg;
                static dispatch_once_t onceToken;
                dispatch_once (&onceToken, ^{
                    defImg = [[ IDSImageManager sharedManager ] defaultAvatar : CircleStyle ];
                });
                [ self . avatarImageView sd_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 . nameLabel sizeToFit ];
               
                self . timeLabel . frame = CGRectMake ( CGRectGetMaxX ( self . nameLabel . frame )+ 5 , 0 , 0 , 0 );
                self . timeLabel . text = [ TimeUtil cl_prettyDateWithReference : _chatModel . timestamp ];
                [ self . timeLabel sizeToFit ];
                self . timeLabel . centerY = self . nameLabel . centerY ;
            }
        }];

转载于:https://www.cnblogs.com/firstrate/p/8042486.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值