当前位置: 首页 > news >正文

cell的复用机制和自定义cell

cell的复用机制和自定义cell

UITableView

在学习cell之前,我们需要先了解UITableViewUITableView继承于UIScrollView,拥有两个两个相关协议

UITableViewDelegateUITableViewDataSource,前者用于显示单元格,设置行高以及对单元格进行指定操作,插入头视图和脚视图,后者用于设置TableView的section和row的数量(section相当于行,row相当于列)。

cell的复用方式

非注册

使用非注册方法,对cell类进行注册,我们需要对cell进行判空

  • 非注册方式是直接通过实例化单元格对象,并在需要时手动创建和配置每个单元格。
  • 这种方式通常在简单的表格或特殊情况下使用,不需要频繁的单元格重用。
  • 使用非注册方式时,可以通过实例方法 UITableViewCell(style:reuseIdentifier:) 或其他自定义初始化方法来创建单元格对象。
  • 每次需要显示新的单元格时,都会实时创建新的单元格对象,而不会尝试重用已存在的单元格。
  • 非注册方式的优点是简单直接,适用于一些简单的表格或特殊的使用情况。
- (void)viewDidLoad
{[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{static NSString *identifier = @"mycell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];}// Configure the cell......return cell;
}

注册

  • 注册单元格是通过调用 UITableView 的 register(_:forCellReuseIdentifier:) 方法来完成的。通常在 viewDidLoad 或类似的初始化方法中执行。

  • 在注册单元格时,您需要提供一个标识符(ReuseIdentifier),用于标识特定类型的单元格。

  • 当需要创建新的单元格时,UITableView 会使用注册的标识符来实例化单元格对象,并自动管理单元格的重用。

  • 每次调用 dequeueReusableCell(withIdentifier:for:) 方法获取单元格时,UITableView 都会尝试从重用池中获取已注册的单元格,如果池中没有可重用的单元格,则根据注册信息创建新的单元格。

  • 注册单元格的好处是可以提高性能,因为它使 UITableView 能够有效地管理单元格的重用和内存占用,从而避免不必要的创建和销毁。

- (void)viewDidLoad 
{[super viewDidLoad];// 如果使用代码自定义 Cell[self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:@"myCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{static NSString *identifier = @"mycell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];// Configure the cell......return cell;
}

区别

  1. 使用注册方法在程序的实现之中不需要进行判空操作,是因为已经在初始化阶段对需要使用的cell类进行注册,所以就可以免去判空的操作
  2. 我们可以注意到在获取 Cell 时,两种方式调用了不同的 method,dequeueReusableCellWithIdentifier:identifier第一个 method 用在了非注册的方式里,equeueReusableCellWithIdentifier:identifier forIndexPath:indexPath第二个 method 用在了需要注册的方式里。

cell的复用原理

cell的复用原理是使用三个容器进行实现

  1. Cell的缓存字典和Section的缓存Array:
    • 为了提高复用性能,可以使用缓存字典和缓存数组来存储已创建的 UITableViewCell 实例。
    • 缓存字典的键是重用标识符,值是一个数组,每个元素都是具有相同重用标识符的可复用单元格实例。
    • 缓存数组用于缓存每个 section 中的单元格数据,使得访问和管理每个 section 的单元格更加方便。
  2. 可复用集合(Mutable Set):
    • 可复用集合是一个可变的集合(如 NSMutableSet),用于存放当前可复用的 UITableViewCell 实例。
    • 当单元格滚动离开屏幕时,它会被添加到可复用集合中,以备后续的复用。
    • 当需要获取可复用的单元格时,首先从可复用集合中检查是否有可用的单元格实例。

这个可复用的集合其实就是我们所说的复用池,也称之为_reusableCells:

关于cell的复用

单元格在显示的时候就会创建视图中可看到的单元格数+ 1的单元格。在UITableView滚动的过程中,会使用复用机制进行对单元格对象的管理,避免了频繁创建和销毁单元格,以达到提高性能和内存的利用率。当某个单元格离开屏幕范围时,它会被回收并放入_reusableCells集合中,等待被重复使用。当新的单元格需要显示时,UITableView会首先尝试从_reusableCells中获取一个可复用的单元格对象,如果_reusableCells中没有可用的单元格,则会通过实例化新的UITableViewCell对象来满足需求。

即通俗的来说,当滑动的等操作使原本在屏幕上的cell不显示在屏幕上,就会将移除到单元格中的复用池之中,然后再加载新的cell的时候也并不是新创建一个cell,而是直接从对象池中取出一个cell对象,然后给它的相关属性赋上新的值,从而实现cell的复用。

自定义cell

由于系统给出的cell只能够实现文字,所有时候我们就需要使用自定cell,来生成我们想要的单元格格式

自定义cell的实现需要以下步骤

  1. 创建 UITableViewCell 的子类
  2. 定义 UITableViewCell 的界面和布局
  3. 注册和使用自定义 UITableViewCell

步骤一:

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface JCTableViewCell : UITableViewCell@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UIButton *button;@endNS_ASSUME_NONNULL_END

步骤二:

#import "JCTableViewCell.h"@implementation JCTableViewCell- (void)awakeFromNib {[super awakeFromNib];// Initialization code
}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated];// Configure the view for the selected state
}- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];self.label = [[UILabel alloc] init];self.label.text = @"子视图";self.label.backgroundColor = [UIColor redColor];[self.contentView addSubview:_label];self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];[self.button setTitle:@"按钮" forState:UIControlStateNormal];[self.button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];[self.contentView addSubview:self.button];return self;
}- (void)layoutSubviews {[super layoutSubviews];self.label.frame = CGRectMake(0, 0, 70, 80);self.button.frame = CGRectMake(100, 0, 70, 70);
}- (void)buttonTapped {// 在此处理按钮点击事件NSLog(@"按钮被点击");
}@end

步骤三:

#import "ViewController.h"
#import "JCTableViewCell.h"
@interface ViewController ()@endstatic NSString *str = @"id";
@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor redColor];tview = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];tview.delegate = self;tview.dataSource = self;tview.backgroundColor = [UIColor grayColor];[tview registerClass:[JCTableViewCell class] forCellReuseIdentifier:str];[self.view addSubview:tview];
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {return 80.0; // 设置为适当的单元格高度
}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{return 5;
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {JCTableViewCell *cell = [tview dequeueReusableCellWithIdentifier:str];return cell;
}
@end

相关文章:

cell的复用机制和自定义cell

cell的复用机制和自定义cell UITableView 在学习cell之前&#xff0c;我们需要先了解UITableView。UITableView继承于UIScrollView&#xff0c;拥有两个两个相关协议 UITableViewDelegate和UITableViewDataSource&#xff0c;前者用于显示单元格&#xff0c;设置行高以及对单…...

Redis 双写一致原理篇

前言 我们都知道,redis一般的作用是顶在mysql前面做一个"带刀侍卫"的角色,可以缓解mysql的服务压力,但是我们如何保证数据库的数据和redis缓存中的数据的双写一致呢,我们这里先说一遍流程,然后以流程为切入点来谈谈redis和mysql的双写一致性是如何保证的吧 流程 首先…...

《软件定义安全》之四:什么是软件定义安全

第4章 什么是软件定义安全 1.软件定义安全的含义 1.1 软件定义安全的提出 虚拟化、云计算、软件定义架构的出现&#xff0c;对安全体系提出了新的挑战。如果要跟上网络演进的步伐和业务快速创新的速度&#xff0c;安全体系应该朝以下方向演变。 &#x1d7ed; 安全机制软件…...

将AIRNet集成到yolov8中,实现端到端训练与推理

AIRNet是一个图像修复网络,支持对图像进行去雾、去雨、去噪声的修复。其基于对比的退化编码器(CBDE),将各种退化类型统一到同一嵌入空间;然后,基于退化引导恢复网络(DGRN)将嵌入空间修复为目标图像。可以将AIRNet的输出与yolov8进行端到端集成,实现部署上的简化。 本博…...

hcache缓存查看工具

1、hcache概述 hcache是基于pcstat的&#xff0c;pcstat可以查看某个文件是否被缓存和根据进程pid来查看都缓存了哪些文件。hcache在其基础上增加了查看整个操作系统Cache和根据使用Cache大小排序的特性。官网:https://github.com/silenceshell/hcache 2、hcache安装 2.1下载…...

Java 数据类型 -- Java 语言的 8 种基本数据类型、字符串与数组

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 004 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…...

kafka-生产者事务-数据传递语义事务介绍事务消息发送(SpringBoot整合Kafka)

文章目录 1、kafka数据传递语义2、kafka生产者事务3、事务消息发送3.1、application.yml配置3.2、创建生产者监听器3.3、创建生产者拦截器3.4、发送消息测试3.5、使用Java代码创建主题分区副本3.6、屏蔽 kafka debug 日志 logback.xml3.7、引入spring-kafka依赖3.8、控制台日志…...

免费!GPT-4o发布,实时语音视频丝滑交互

We’re announcing GPT-4o, our new flagship model that can reason across audio, vision, and text in real time. 5月14日凌晨&#xff0c;OpenAI召开了春季发布会&#xff0c;发布会上公布了新一代旗舰型生成式人工智能大模型【GPT-4o】&#xff0c;并表示该模型对所有免费…...

DevOps的原理及应用详解(四)

本系列文章简介: 在当今快速变化的商业环境中,企业对于软件交付的速度、质量和安全性要求日益提高。传统的软件开发和运维模式已经难以满足这些需求,因此,DevOps(Development和Operations的组合)应运而生,成为了解决这些问题的有效方法。 DevOps是一种强调软件开发人员(…...

关于选择,关于处事

一个人选择应该选择的是勇敢&#xff0c;选择不应该选择的是无奈。放弃&#xff0c;不该放弃的是懦夫&#xff0c;不放弃应该放弃的是睿智。所以&#xff0c;碰到事的时候要先静&#xff0c;先不管什么事&#xff0c;先静下来&#xff0c;先淡定&#xff0c;先从容。在生活里要…...

大话设计模式解读02-策略模式

本篇文章&#xff0c;来解读《大话设计模式》的第2章——策略模式。并通过Qt和C代码实现实例代码的功能。 1 策略模式 策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式的特点&#…...

展会邀请 | 龙智即将亮相2024上海国际嵌入式展,带来安全合规、单一可信数据源、可追溯、高效协同的嵌入式开发解决方案

2024年6月12日至14日&#xff0c;备受全球嵌入式系统产业和社群瞩目的2024上海国际嵌入式展&#xff08;embedded world china 2024&#xff09;即将盛大开幕&#xff0c;龙智将携行业领先的嵌入式开发解决方案亮相 640展位 。 此次参展&#xff0c;龙智将全面展示专为嵌入式行…...

codeforce round951 div2

A guess the maximum 问题&#xff1a; 翻译一下就是求所有相邻元素中max - 1的最小值 代码&#xff1a; #include <iostream> #include <algorithm>using namespace std;const int N 5e4;int a[N]; int n;void solve() {cin >> n;int ans 0x3f3f3f3f;…...

arcgis开发记录

目录 文章目录 [toc]**arcgis JavaScript API安装**1. arcgisAPI下载地址&#xff1a;https://developers.arcgis.com/downloads/2. 4.4版本API&#xff1a;本地配置3. 3.18版本修改方法 **angular2中加载arcgis JS API**** arcgis加载图层 并显示图层上点的信息****使用图层上…...

RPA-UiBot6.0数据整理机器人—杂乱数据秒变报表

前言 友友们是否常常因为杂乱的数据而烦恼?数据分类、排序、筛选这些繁琐的任务是否占据了友友们的大部分时间?这篇博客将为友友们带来一个新的解决方案,让我们共同学习如何运用RPA数据整理机器人,实现杂乱数据的快速整理,为你的工作减负增效! 在这里,友友们将了…...

Application UI

本节包含关于如何用DevExpress控件模拟许多流行的应用程序ui的教程。 Windows 11 UI Windows 11和最新一代微软Office产品启发的UI。 Office Inspired UI Word、Excel、PowerPoint和Visio等微软Office应用程序启发的UI。 如何&#xff1a;手动构建Office风格的UI 本教程演示…...

关于 Redis 中集群

哨兵机制中总结到&#xff0c;它并不能解决存储容量不够的问题&#xff0c;但是集群能。 广义的集群&#xff1a;只要有多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称之为一个“集群”&#xff0c;例如主从结构中的哨兵模式。 狭义的集群&#xff1a;redis 提供的…...

C++必修:探索C++的内存管理

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. C/C的内存分布 我们首先来看一段代码及其相关问题 int globalVar 1; static…...

python列表---基本语法(浅拷贝,深拷贝等)

文章目录 引言:列表的注意事项1 list中的浅拷贝与深拷贝1.1浅拷贝(Shallow Copy)浅拷贝的方法浅拷贝的效果1.2深拷贝(Deep Copy)深拷贝的方法深拷贝的效果1.3 总结:浅拷贝 vs 深拷贝1.4 为什么浅拷贝顶层元素如果是不可变数据就不能共享,不是传的是引用就相当于传的是地…...

go语言接口之sort.Interface接口

排序操作和字符串格式化一样是很多程序经常使用的操作。尽管一个最短的快排程序只要15 行就可以搞定&#xff0c;但是一个健壮的实现需要更多的代码&#xff0c;并且我们不希望每次我们需要的时候 都重写或者拷贝这些代码。 幸运的是&#xff0c;sort包内置的提供了根据一些排序…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...