【iOS】UITableViewCell的重用问题解决方法

news2024/9/22 10:03:44

我自己在实验中对cell的重用总结如下:

非自定义Cell和非自定义cell的复用情况一样:

  1. 第一次加载创建tableView的时候,是屏幕上最多也显示几行cell就先创建几个cell,此时复用池里什么都没有
  2. 开始下滑tableView,刚开始滑动时,由于第一行没有完全滑出屏幕进复用池时,下面的新cell已经显示到屏幕上了,所以下方这个新滑出来的cell就是新创建的cell而不是复用的cell(复用时也得看新加载的cell和复用池中的备用cell有没有同类型的id,没有就不复用),然后接着滑动,第一个cell就完全出屏幕进入复用池了,下面我们接着滑动,接着那个需要新显示出来的cell如果和复用池中我们保存的第一个cell是同种id,如果是就直接拿来复用,如果不是就新创建(判断是否能复用和新创建的操作都在cell的编辑函数:cellForRowAtIndexPath:中)
  3. 上滑tableView和下滑原理基本一致,完全出屏幕的入复用池,需要新加载到屏幕的cell,先看池中有没有同id的cell,有了就复用,没有就创建。

下面我们讲一个使用cell时需要注意的点:

复用时从复用池中取出来的cell可以是已经捆绑过数据或者加过子视图的,所以,如果有必要,要清除数据,比如(label的text)和remove掉add过的子视图(使用tag),否则就有可能造成复用后出现显示的内容不符预期的情况,比如说我们有一个开始创建id为@"test"的cell,我们在执行cell的编辑函数:cellForRowAtIndexPath:中有一个判断分支,符合某种情况时需要在cell上显示一个button,而不符合那种情况的时候就不显示button,而恰好我们这个cell符合情况,于是就添加了button相关的数据,然后显示出了button,接着我们滑动了tableView,导致我们刚才创建的这个id为@"test"的cell进入了复用池,然后再继续下滑的时候有一个新的id为@"test"的cell需要被加载出来,于是就查看了复用池,发现里面有同id的cell,所以就直接拿来复用了,复用的时候对里面的数据进行了自己的设定,本类好像没什么问题,但是恰好这个新cell不符合那个要显示button的条件,然后就不会去执行对button添加数据的操作,我们预想着这个新cell和之前我们创建的id为@"test"的cell的区别就是新的没有button,旧的有button,然后两者其他控件也就是数据内容不同(比如label的text不一样这些),但是实际情况却是这个新创建的cell上面显示的依然存在button,和我们预想的不一致,其原因就是复用时所取出来的旧cell是已经捆绑过数据且加过子视图的,虽然我们新cell创建时没有走对button添加数据的代码,但是由于旧cell走过了,且向button添加的数据都在,所以就导致新cell上面就有一个和旧cell一模一样的button。

这就是复用中可能存在的一个常见的难搞的问题,但是解决起来其实也非常简单,重点在于:避免重用机制出错

以下有三种方法:(最推荐第三种

  1. 重用机制调用的就是dequeueReusableCellWithIdentifier这个方法,方法的意思就是“出列可重用的cell”,因而只要将它换为cellForRowAtIndexPath(只从要更新的cell的那一行取出cell),就可以不使用重用机制,因而问题就可以得到解决,但会浪费一些空间。
    在这里插入图片描述

  2. 为每个cell指定不同的重用标识符(reuseIdentifier)来解决。重用机制是根据相同的标识符来重用cell的,标识符不同的cell不能彼此重用。

NSString *identifier = [NSString stringWithFormat:@"TimeLineCell%d%d",indexPath.section,indexPath.row];
  1. 在新cell创建走编辑函数:cellForRowAtIndexPath:时,在里面加一段操作,去remove多余的那个子视图或者清除旧数据

在这里插入图片描述

而且依我本人之见,最好使用清除旧数据而不是remove多余的子视图。因为这个正在新建的cell后面也许也会进入自动释放池,而且它到时候也可能会被拿来复用,如果那个复用它的cell刚好需要显示button而这个被复用的cell连button这个视图都没添加到cell上,那直接向button添加数据时程序就会crash,所以清除所有数据是不错的选择,反正每次执行编辑函数:cellForRowAtIndexPath:时都会为对应行组的cell重新添加那些子视图上的数据(相当于覆写了旧数据),我们只需要在所有的重新添加数据操作之前讲被复用的cell上子视图的数据全删了就行。
但是如果偏要走remove子视图的方法也不是不行,我们可以巧妙点,从复用池取出来要被复用的cell之后直接重新alloc初始化一下这个被复用的cell,相当于之前清空了原本保存的所有子视图的全部数据,而原本添加到cell上的子视图都还在,只是没有数据不显示罢了,这也是很好的手段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2043367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可视化编程-七巧低代码入门02

1.1.什么是可视化编程 非可视化编程是一种直接在集成开发环境中(IDE)编写代码的编程方式,这种编程方式要求开发人员具备深入的编程知识,开发效率相对较低,代码维护难度较大,容易出现错误,也需要…

最新的APS高级计划排程系统推动的MRP供应链计划是什么?

在当下“内卷”的市场环境下,制造业的订单需求从过去大批量标准品生产已经演变成小批量、多订单的非标订单生产,这对制造业的供应链提出了更高的要求。为了应对市场实现产销平衡,中大型的企业都开始重视供应链的建设工作,以应对企…

数字签名和CA数字证书的核心原理和作用

B站讲解视频,讲述HTTPS CA认证的整个行程过程与原理 https://www.bilibili.com/video/BV1mj421d7VE

[Qt][Qt 文件]详细讲解

目录 1.输入输出设备类2.文件读写类3.文件和目录信息类 1.输入输出设备类 在Qt中,⽂件读写的类为QFile,其⽗类为QFileDevice QFileDevice提供了⽂件交互操作的底层功能QFileDevice的⽗类是QIODevice,其⽗类为QObject QIODevice是Qt中所有I/O…

【数学建模备赛】Ep05:斯皮尔曼spearman相关系数

文章目录 一、前言🚀🚀🚀二、斯皮尔曼spearman相关系数:☀️☀️☀️1. 回顾皮尔逊相关系数2. 斯皮尔曼spearman相关系数3. 斯皮尔曼相关系数公式4. 另外一种斯皮尔曼相关系数定义5. matlab的用法5. matlab的用法 三、对斯皮尔曼相…

立仪光谱共焦传感器行业应用|透明胶水高度测量

01|检测需求:透明胶水高度测量 02|检测方式 根据客户要求及观察我们使用立仪科技D40A26XL镜头搭配E系列控制器进行测量 03|光谱共焦测量结果 经过测量可以得出胶水的高度为1076.406μm 04|光谱共焦侧头 D40A26XL侧头…

uniapp接口请求this.$request

代码示例: createPhoto(url) {this.$request({url: /emp/gallery-photo/create,//后端接口method: post,//请求方法header: {//请求头tenant-id: 1,},data: {//请求参数galleryId: this.albumId,empUserId: this.empUserId,"url": url,}}).then((res) &…

JVM -垃圾回收器

本人在这篇文章中讲解了垃圾回收机制,这为前置知识 美团一面面经:Threadlocal(线程局部变量的原理)->内存泄漏问题->垃圾回收机制_threadlocal回收-CSDN博客 首先对前置知识漏洞做一个补充:ja…

时序电路实验-节拍脉冲发生器

二、实验目的 掌握节拍脉冲发生器的设计方法,理解节拍脉冲发生器的工作原理。 三、实验环境 PC计算机 四、实验内容 单步/连续节拍发生电路设计 增加两个2-1多路选择器,可将图3.3所示电路修改为图3.5所示电路。 图3.5单步/连续节拍脉冲发生器工作波…

如何进行长截图的两种方法

前言 本文主要讲2种截图方式,分别是谷歌和QQ。 谷歌分为Web端 和 移动端,选一种即可。 第一种:谷歌浏览器控制台自带的 1.先把控制台语言更改为中文,方便查看 ①.按F12,点击设置面板 ②.修改语言为中文并关闭 ③.点击…

七、OpenCVSharp 中的图像边缘检测

文章目录 简介一、Sobel 算子1. 水平和垂直方向的 Sobel 算子2. 梯度幅值和方向的计算3. Sobel 算子的参数调整和效果优化二、Canny 边缘检测1. Canny 算法的步骤详解(高斯平滑、梯度计算、非极大值抑制、双阈值检测)2. 高低阈值的选择对边缘检测结果的影响3. Canny 边缘检测…

阿里云服务器CentOS7安装MinIO

1. 概述 MinIO是一个开源的分布式对象存储服务器,支持S3协议并且可以在多个节点上实现数据的高可用和容错,采用Go语言开发,拥有轻量级、高性能、易部署等特点,并且可以自由选择底层存储介质。 MinIO主要特点: 高性能&…

《MySQL全面指南:从基础到精通》专栏大纲

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Linux 平台 PulseAudio 音频播放数据通路 I

Linux 内核中,音频子系统由 ALSA 框架实现,用户空间应用程序通过 ALSA 框架向 devtmpfs 虚拟文件系统,即 /dev/snd 目录下导出的一组紧密相关的设备文件,如 controlC0、pcmC0D0c 和 pcmC0D0p 等与 Linux 内核音频子系统交互&#…

ORB-SLAM3(Failed to load image)问题解决(WSL2配置)

一、概述 因为需要使用wsl2进行视觉SLAM的配置,我选择的事ORB-SLAM3,原来之前也配置过,比较熟悉,这次换了一个新的系统wsl2下的Ubuntu20.04下面进行配置。中间出现了一些跟原来不太一样的问题。这里将遇到的问题进行记录一下。 二…

【体外诊断】基于ARM+FPGA全自动核酸提取仪

全自动核酸提取仪 ARM: NXP IMX8/IMX6U, TI AM62X/AM5728, RK: RK3588/RK3568 FPGA: Xilinx A7/K7/SPANTAN6/ZYNQ/MPSOC, 国产复旦微、安路、高云、紫光 全自动核酸提取仪是一种高精度、高效率的核酸提取设备,主要用于对样本进行核酸提取。其原理是使用自动化控制系统,通过多…

mysql B+ 树

问题: mysql innodb引擎 B树主键自增,插入数据时是从中间分裂,还是使用页尾部元素作为父节点的值然后添加一个新页,或者说主键连续自增,mysql有没有做这样的优化? 以下是Chat GPT给出的回答:

window搭建代理ip池:详细的搭建指南分享

在Windows上搭建代理IP池的指南 在进行网络爬虫或其他需要频繁请求的任务时,建立一个代理IP池可以有效提高抓取效率和隐私保护。本文将详细介绍如何在Windows环境下搭建一个简单的代理IP池。 1. 准备工作 在开始之前,请确保你具备以下条件&#xff1a…

【排序汇总】这里记录一切与搜索排序相关的内容~(更新ing)

目录 经典算法快速排序核心思想cpp代码 二分查找核心思想cpp代码 具体题目荷兰旗问题-颜色分类 (leetcode75)思路cpp代码 数组中的第K个最大元素 (leetcode215)思路:快速选择cpp代码 经典算法 快速排序 经典面试手撕题,刚好明天又要面试百度了&#xf…

固态硬盘用mbr还是GPT?固态硬盘分区类型用mbr还是GPT分析

固态硬盘用mbr还是GPT?答:固态硬盘分区类型用mbr还是gpt其实取决于你对分区要求及引导模式。我们知道现在的引导模式有uefi和legacy两种引导模式,如果采用的是uefi引导模式,分区类型对应的就是gpt分区(guid),如果引导模…