浅谈iOS中UITableView的复用机制

浅谈对UITableView复用机制的了解

  • 我们先给出整体代码,然后逐步分析
#import "ViewController.h"
#define width [UIScreen mainScreen].bounds.size.width
#define height [UIScreen mainScreen].bounds.size.height
static NSString * identifying=@"cell";
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic,strong) UITableView* tableview;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //接下来是创建表视图
    //系统自己有两种UITabelView样式:
    //UITableViewStylePlain   平铺类型
    //UITableViewStyleGrouped  分组类型
    _tableview=[[UITableView alloc]initWithFrame:CGRectMake(0,0,width,height) style:UITableViewStylePlain];
    //让表视图的代理是当前控制器
    _tableview.delegate=self;
    _tableview.dataSource=self;
    //添加该控制器到视图上
    [self.view addSubview:_tableview];
}
//接下来实现UITableViewDelegate中的方法
#pragma  mark -UITableViewDegelates
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100;
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell=[_tableview dequeueReusableCellWithIdentifier:identifying];
    if(cell==nil)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifying];
    }
    cell.textLabel.text=[NSString stringWithFormat:@"第%ld行",indexPath.row];
    NSLog(@"adress -----%p-------第%ld行",cell,indexPath.row);
    return cell;
}

@end

首先我们先创建一个表视图

- (void)viewDidLoad {
    [super viewDidLoad];
    //接下来是创建表视图
    //系统自己有两种UITabelView样式:
    //UITableViewStylePlain   平铺类型
    //UITableViewStyleGrouped  分组类型
    _tableview=[[UITableView alloc]initWithFrame:CGRectMake(0,0,width,height) style:UITableViewStylePlain];
    //让表视图的代理是当前控制器
    _tableview.delegate=self;
    _tableview.dataSource=self;
    //添加该控制器到视图上
    [self.view addSubview:_tableview];
}

这里可以看到,我们在创建一个UITableView的一个对象时,设置了它的类型,其实系统自己的UITableView样式有两种:
1. UITableViewStylePlain(其样式是方形的)
2. UITableViewStyleGrouped(其样式是圆角形)

创建好对象之后,我们要设置表视图的代理

   //让表视图的代理是当前控制器
    _tableview.delegate=self;
    _tableview.dataSource=self;
    //添加该控制器到视图上
    [self.view addSubview:_tableview];

我们在看接下来的一段代码:这些都是协议里所定义的方法,若读者对协议的有关内容不是所了解,请自行搜索!本文这里不做介绍

>  - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100;
}

这里是设置cell的高度
接下来就是最重要的了:
并且是本篇文章的重点,即重用机制!!!

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell=[_tableview dequeueReusableCellWithIdentifier:identifying];
    if(cell==nil)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifying];
    }
    cell.textLabel.text=[NSString stringWithFormat:@"第%ld行",indexPath.row];
    NSLog(@"adress -----%p-------第%ld行",cell,indexPath.row);
    return cell;
}

我们来看这一段:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}

这是设置的是cell的总数,这个比较简单,我们接着看

- (UITableViewCell *   )tableView:(UITableView *  )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell=[_tableview dequeueReusableCellWithIdentifier:identifying];
    if(cell==nil)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifying];
    }
    cell.textLabel.text=[NSString stringWithFormat:@"第%ld行",indexPath.row];
    NSLog(@"adress -----%p-------第%ld行",cell,indexPath.row);
    return cell;
}

我们一句一句的看
首先:

   UITableViewCell * cell=[_tableview dequeueReusableCellWithIdentifier:identifying];

这一句意思是:根据标识符identifying从重用队列中取出一个cell,由于刚开始重用队列是空的,因此我们取出的cell也是空的。那么,如果说cell是空的,那么会执行下面的语句:

 if(cell==nil)
    {
        cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifying];
    }

这句的意思是:cell为空,那么就会执行这个语句创建UITableViewCellStyleDefault类型的cell,并将其标识为identifying.
其实系统自己的UITableViewCell类型有四种:
* UITableViewCellStyleDefault
* UITableViewCellStyleSubtitle
* UITableViewCellStyleValue1
* UITableViewCellStyleValue2
好,这就创建好了一个cell,那么需要第二个的时候,也是类似的步骤,直到创建的数目已达到你创建的cell的个数,
那么,比如说,你创建了10个cell,但是我们需要比如说100个,(这就体现了复用机制的好处了:可以节约资源,就是说,如果我需要100,200,甚至更多个cell,我不需要创建这么多个的cell,我只需要创建几个,然后一直在重复使用就行了,这极大的节约了内存空间,因此复用机制是非常重要的一种机制!!!)
回到主题,假如我们此刻需要第十一个cell,那么该怎么办呢?

当我们移动cell时,就比如微信里我们上划朋友列表,此时我们可以看到下面的cell,而此时,最上面的cell,会随着你逐渐下滑而逐渐隐藏,我们称隐藏的cell是被放进了重用了队列,等以后需要时在拿出来使用。比如,我们现在要显示第十一个cell,那么会通过上面的方法,即

> UITableViewCell* cell=[_tableview dequeueReusableCellWithIdentifier:identifying];

在重用队列中寻找表示为identifying的cell,而我们知道,此时由于第一个cell被放到了重用队列中,且它的标识符不是空,即上面我们已经创建它使它的标识符为identifying,所以第十一个cell会重用第一个cell,
由此循环. (我们在此说明一下,只有当你所创建的cell数多于屏幕能够显示的数目时才会发生复用机制)
我们来看一下程序运行结果:
这是我们设置cell的数量为十是的结果:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 6;
}

下面我们换一下初始cell的数目:

>(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 30;
}

2018-06-17 19:51:42.464888+0800 TabelView[1335:496462] adress -----0x7fae89824800-------第0行
2018-06-17 19:51:42.473950+0800 TabelView[1335:496462] adress -----0x7fae8a89a000-------第1行
2018-06-17 19:51:42.474752+0800 TabelView[1335:496462] adress -----0x7fae8983ba00-------第2行
2018-06-17 19:51:42.475351+0800 TabelView[1335:496462] adress -----0x7fae8a02ae00-------第3行
2018-06-17 19:51:42.475881+0800 TabelView[1335:496462] adress -----0x7fae89821400-------第4行
2018-06-17 19:51:42.476476+0800 TabelView[1335:496462] adress -----0x7fae8b023e00-------第5行
2018-06-17 19:51:42.477039+0800 TabelView[1335:496462] adress -----0x7fae89821a00-------第6行
2018-06-17 19:51:42.477593+0800 TabelView[1335:496462] adress -----0x7fae8b046800-------第7行
2018-06-17 19:51:42.478323+0800 TabelView[1335:496462] adress -----0x7fae8b048400-------第8行
2018-06-17 19:51:42.478921+0800 TabelView[1335:496462] adress -----0x7fae8a89c000-------第9行
2018-06-17 19:51:42.479556+0800 TabelView[1335:496462] adress -----0x7fae8b048a00-------第10行
2018-06-17 19:51:42.480109+0800 TabelView[1335:496462] adress -----0x7fae8b044000-------第11行
2018-06-17 19:51:42.480627+0800 TabelView[1335:496462] adress -----0x7fae8a89c600-------第12行
2018-06-17 19:51:42.502872+0800 TabelView[1335:496462] adress -----0x7fae89813200-------第13行
2018-06-17 19:51:42.503415+0800 TabelView[1335:496462] adress -----0x7fae8a02b400-------第14行
2018-06-17 19:51:42.503973+0800 TabelView[1335:496462] adress -----0x7fae8b044600-------第15行
2018-06-17 19:51:42.504519+0800 TabelView[1335:496462] adress -----0x7fae8a835800-------第16行
2018-06-17 19:51:49.346941+0800 TabelView[1335:496462] adress -----0x7fae8a835800-------第8行
2018-06-17 19:51:49.414429+0800 TabelView[1335:496462] adress -----0x7fae89824800-------第9行
2018-06-17 19:51:49.549362+0800 TabelView[1335:496462] adress -----0x7fae8a89a000-------第10行
2018-06-17 19:51:49.797156+0800 TabelView[1335:496462] adress -----0x7fae8983ba00-------第11行
2018-06-17 19:51:50.022079+0800 TabelView[1335:496462] adress -----0x7fae8a02ae00-------第12行
2018-06-17 19:51:50.134543+0800 TabelView[1335:496462] adress -----0x7fae89821400-------第13行
2018-06-17 19:51:50.298947+0800 TabelView[1335:496462] adress -----0x7fae8b023e00-------第14行
2018-06-17 19:51:50.515688+0800 TabelView[1335:496462] adress -----0x7fae89821a00-------第15行
2018-06-17 19:51:50.931506+0800 TabelView[1335:496462] adress -----0x7fae8b046800-------第16行
2018-06-17 19:51:52.283601+0800 TabelView[1335:496462] adress -----0x7fae8a835800-------第17行
2018-06-17 19:51:52.553366+0800 TabelView[1335:496462] adress -----0x7fae89824800-------第18行
2018-06-17 19:51:52.665960+0800 TabelView[1335:496462] adress -----0x7fae8a89a000-------第19行
2018-06-17 19:51:53.382396+0800 TabelView[1335:496462] adress -----0x7fae8a02ae00-------第12行

可以看到在第八行开始复用

参考资料:

  1. https://www.jianshu.com/p/2ea77fa2084a
  2. https://blog.csdn.net/wuzesong/article/details/52225487
  3. https://blog.csdn.net/qq_18608029/article/details/51918759
发布了32 篇原创文章 · 获赞 10 · 访问量 3434

猜你喜欢

转载自blog.csdn.net/shandamengcheng/article/details/80720530
今日推荐