您的位置:首页 > 产品设计 > UI/UE

iOS开发之UI学习-UITableView的复用机制

2016-08-16 22:46 513 查看
    最近编写新功能的时候,偶然间发现有较少开发经验的开发人员对于表视图的单元格的复用问题并不是了解的很透彻,所以在此通过代码的形式快速的教给大家如何理解和运用单元格的复用问题。表视图是在开发中经常使用的控件,而且有时处理的内容量也是非常巨大的,这就需要考虑表视图的性能优化,而最基本的性能优化则是单元格的复用,正所谓基础打得好,才能飞得高,所以需要很好的理解单元格是如何复用的。

    在表视图显示的时候,会创建 (视图中可看的单元格个数+1)个单元格,一旦单元格因为滑动的而消失在我们的视野中的时候,消失的单元格就会进入缓存池(或叫复用池),当有新的单元格需要显示的时候,会先从缓存池中取可用的单元格,获取成功则使用获取到的单元格,获取失败则重新创建心的单元格,这就是整个的复用机制。但是如何进行复用,这里有两种方式:

第一种方式:

自己手动创建新的单元格

#import "ViewController.h"

#define width [UIScreen mainScreen].bounds.size.width
#define height [UIScreen mainScreen].bounds.size.height

static NSString *identifying = @"标识";

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

//创建表视图
/*
UITableViewStylePlain 平铺类型
UITableViewStyleGrouped 分组类型
*/
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, width, height) style:UITableViewStylePlain];
//让当前控制器成为表视图的代理
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
}

#pragma mark - UITableViewDelegate 代理方法
//设置cell的行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

return 100;
}

#pragma mark - UITableViewDataSource 数据源
//设置cell的个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

return 20;
}

//设置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

//1.根据标识去缓存池中去取cell
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:identifying];

//2.根据是否取到了可用的cell来判断是否需要重新创建cell(手动创建新的单元格)
if (cell == nil){

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifying];
}
//3.设置单元格的显示数据
cell.textLabel.text = [NSString stringWithFormat:@"第%ld行",indexPath.row];

//通过打印cell的地址,我们来查看是否复用了cell
NSLog(@"address --- %p ----- 第%ld行",cell, indexPath.row);

return cell;
}

@end


通过打印的地址我们可以看出复用:



第二种方式:

通过注册单元格类的方式,由表视图自己创建单元格

#import "ViewController.h"

#define width [UIScreen mainScreen].bounds.size.width
#define height [UIScreen mainScreen].bounds.size.height

static NSString *identifying = @"标识";

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

//创建表视图
/*
UITableViewStylePlain 平铺类型
UITableViewStyleGrouped 分组类型
*/
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, width, height) style:UITableViewStylePlain];
//让当前控制器成为表视图的代理
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];

//注册单元格的类型
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:identifying];
}

#pragma mark - UITableViewDelegate 代理方法
//设置cell的行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

return 100;
}

#pragma mark - UITableViewDataSource 数据源
//设置cell的个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

return 20;
}

//设置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

//1.根据标识去缓存池中去取cell
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:identifying];

//2.倘若根据ID标识来判断有没有对应的cell类型,当缓存池中没有可以复用的cell的时候,会根据注册的类型自动创建cell

//3.设置单元格的显示数据
cell.textLabel.text = [NSString stringWithFormat:@"第%ld行",indexPath.row];

//通过打印cell的地址,我们来查看是否复用了cell
NSLog(@"address --- %p ----- 第%ld行",cell, indexPath.row);

return cell;
}

@end

通过打印的地址我们可以看出复用:



两种单元格的复用的方式存在着细微的差别,新手一般情况下会不太理解,但是只要仔细观看以上的代码,或者将代码直接粘贴到新创建的工程中去,然后运行,可以得出和我截图出的一样的结果。希望以上代码能够帮助对于表视图的单元格复用不太理解的开发人群。当然这里只是简单的讲解了一下单元格的重用机制,在实际的开发过程中,可能会因为不同的展示效果,需要合理的利用单元格的复用。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: