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. 【27.34%】【codeforces 611D】New Year and Ancient Prophecy

    time limit per test2.5 seconds memory limit per test512 megabytes inputstandard input outputstandard ...

  2. linux系统下信号具体解释2

    信号是UNIX 系统所使用的进程通信方法中,最古老的一种.信号不但能从内核发往一个进程,也能从一个进程发往还有一个进程.比如,用户在后台启动了一个要运行较长时间的程序,假设想中断其运行,能够用kill ...

  3. 利用伪元素before实现自定义checkbox样式

     原理:label标签的for属性可以将文字与复选框进行关联,点击文字可以同时将复选框选中. 隐藏checkbox标签,利用label标签的before伪元素来实现自定义样式.设置before伪元素的 ...

  4. WPF 设置了阴影效果后,Y轴位置会有变化的问题

    原文:WPF 设置了阴影效果后,Y轴位置会有变化的问题 背景 最近遇到一个动画执行时,文本位置变化的问题.如下图: 如果你仔细看的话,当星星变小时,文本往下降了几个像素. 貌似有点莫名其妙,因为控件之 ...

  5. 打开一个很好的介绍Lucene4 FST文章

    我没有看到源代码.看到这个博客了解一些基本的,像笔者下: http://download.csdn.net/download/guanxinquan/7380591 http://blog.sina. ...

  6. OpenCV For iOS 1:&#160;连接OpenCV 3.0

    本文的内容參考Instant OpenCV for iOS结合最新的开发平台完毕. 本系列文章採用的的开发环境为: 1)Xcode 6 2)OpenCV for iOS 3.0.0 alpha 接下来 ...

  7. Android中的事件处理研究

    处理用户界面事件Handling UI Events 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件.对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件.视图 ...

  8. Android中使用sqlite3操作SQLite

    SQLite库包含一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令.本文档提供一个样使用sqlite3的简要说明. 一.创建数据库:  1.将sqlit ...

  9. 显示dll里的QWidget

    1 新建库->C++库 2 命名(此处为mydll)并选择共享库--下一步--下一步 3 选择所需要的模块(有使用到的都选上)此处勾选前三项QtCore+QtGui+QtWidgets 4 完成 ...

  10. std::string 简单入门

    string的定义原型 typedef basic_string<char, char_traits<char>, allocator<char> > string ...