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. Crystal Report - 水晶报表导出文件的格式设置

    水晶报表中自带的导出和打印功能用起来确实很方便,只不过有时候需要导出的文件并不需要那么多种类型,在网上找到一些朋友的代码总结了一下,可以通过代码实现自定义导出文件类型 首先需要定义一个枚举: publ ...

  2. Jdbc连接MySQL 8时报错“MySQLNonTransientConnectionException: Public Key Retrieval is not allowed”

    一.问题 因停电检修,今天重启服务器后,再启动jboss就报错"MySQLNonTransientConnectionException: Public Key Retrieval is n ...

  3. 入坑cordova

    原文:入坑cordova 因项目需要入坑cordova,奔跑吧骚年,目前只是要求安卓平台,下面都是以安卓为例 最好的学习资料还是官网. https://cordova.apache.org/ http ...

  4. ES6与React中this完全解惑

    计划写很长的篇幅,预计12月初完成. 这篇文章涉及的知识较多,可能一次消化不了,可以渐渐来. 先说结论: 无论是ES6还是React的this,相对于ES5,只是增加了箭头函数this绑定了其封闭上下 ...

  5. 【16.05%】【codeforces 664B】Rebus

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

  6. 更改linux的最大文件描述符限制

    To ensure good server performance, the total number of client connections, database files, and log f ...

  7. Computer system with dual operating modes

    A system switches between non-secure and secure modes by making processes, applications, and data fo ...

  8. PHP设置时区,记录日志文件的方法

    关键字:PHP 时区 时间 日志 <html> <body> <?php date_default_timezone_set('Asia/Hong_Kong'); //s ...

  9. 局部QEventLoop帮助QWidget不消失(也就是有一个局部事件循环始终在运行,导致程序被卡住那里,但仍可以接受事件。说白了就是有一个while语句死活不肯退出,直到收到退出信号)

    熟悉的陌生人 Qt 是事件驱动的,所以当你用Qt的时候,几乎时时刻刻和 QEventLoop 打交道.,只是你可能没有意识到: QCoreApplicaton::exec() QApplication ...

  10. 一个Java工程师的入门级Linux命令集

    0.前言    网上介绍linux的命令的文章一大堆,但是大部分都是流于命令介绍,把命令的所有参数都介绍一遍,但是其实在真正的工作中,很多参数都不会用到.本文总结了我自己常用的一些命令,这些命令都比较 ...