Bug 出现场景:
 
cell中使用加载图片的网络请求出现复用,截图如下:
 
 
 
 
复用原因:
 
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;
            }
        }];

[每天记录一个Bug]Cell中由于block加载网络请求产生的复用的更多相关文章

  1. 其原因可能是堆被损坏,这说明**.exe中或它加载的任何DLL中有Bug

    最近在写一个写日志文件的线程时,调用了HeapAlloc/HeapFree 申请/释放堆缓冲内存.调用HeapFree释放有个条件就是,日志的空闲缓冲队列中内存块超过100个.在测试的时候,发现调用H ...

  2. MVC中在一个视图中,怎么加载另外一个视图?

    在RazorView.cshtml视图: <!--在视图中调用无返回值的方法,视图中调用无返回值的方法,要加上大括号--> <!--在一个视图中,直接加载另外一个视图--> @ ...

  3. ssh中Hibernate懒加载,session问题的学习与理解

    交代本项目中要求获取session的方式如下: public Session getCurrentSession() { // 增删改使用的session,事务必须是开启的(Required,即pro ...

  4. CLR中的程序集加载

    CLR中的程序集加载 本次来讨论一下基于.net平台的CLR中的程序集加载的机制: [注:由于.net已经开源,可利用vs2015查看c#源码的具体实现] 在运行时,JIT编译器利用程序集的TypeR ...

  5. Java--自定义Class并且在内存中编译,加载,实例化

    本文的目的: 使用者在程序运行期间,可以动态的写Java Class,不需要生成任何.Class文件就可以完全在内存中编译,加载,实例化. 1.需要用到的组件介绍 1)JavaCompiler:用于编 ...

  6. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  7. Android中的分页加载

    //----------------------MainActivity中--------------------------------------------------- package com ...

  8. 从零学习Fluter(五):Flutter中手势滑动拖动已经网络请求

    从六号开始搞Flutter,到今天写这篇blog已经过了4天时间,文档初步浏览了一遍,写下了这个demo.demo源码分享在github上,现在对flutter有种说不出的喜欢了.大家一起搞吧! 废话 ...

  9. web中的懒加载

    在Web应用程序中,系统的瓶颈常在于系统的响应速度.如果系统响应速度过慢,用户就会出现埋怨情绪,系统的价值也因此会大打折扣.因此,提高系统响应速度,是非常重要的. Web应用程序做的最多就是和后台数据 ...

随机推荐

  1. 【16.23%】【codeforces 586C】Gennady the Dentist

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  2. 【27.40%】【codeforces 599D】Spongebob and Squares

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. padding百分百值是相对谁的百分比

    先看代码 <head> <meta charset="UTF-8"> <title>Document</title> <sty ...

  4. Opencv目标跟踪—CamShift算法

    CamShift算法全称是"Continuously Adaptive Mean-Shift"(连续的自适应MeanShift算法),是对MeanShift算法的改进算法,可以在跟 ...

  5. 利用WPF建立自己的3d gis软件(非axhost方式)(三)矢量数据显示控制

    原文:利用WPF建立自己的3d gis软件(非axhost方式)(三)矢量数据显示控制 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUwLfrt0zV0bPew 密 ...

  6. Android中使用JUnit测试

    package com.meritit.lottery.test; import java.util.List; import android.test.AndroidTestCase; import ...

  7. 初探js

    第一章   1.JS的位置 1-1.行间 1-2.内嵌 1-3.外联 2.JS的标签位置 页面中的代码在一般情况下会按从上到下的顺序,从左往右的顺序执行. 因此当JS放在了元素上面的时候,就不能正常执 ...

  8. MFC和Qt优缺点 (MFC几乎没有优点、全面下风)

    在网上看到的,拿来和大家一起讨论下. 我曾经使用过来开发过软件,我想和大家分享我使用他们时所体会的不同之处. 我并非一个职业作家,这篇文章可能看起来不如专业的杂志和网站上的那么条理清晰.但是,我在这里 ...

  9. code first迁移(add-migration)的时候 后面信息不能有中文 中文报错 "不支持给定路径的格式。"

  10. C#中的String.Format介绍

    关键字:C# string.format作者:txw1958原文:http://www.cnblogs.com/txw1958/archive/2012/11/15/csharp-string_for ...