IOS 列表重用机制

      昨天,接到一份“人人影视“面试的邀请,人人影视的HR说我内推网上的简历太简单了,问我有木有更详细的简历,随后我发了一份我精心制作的电子简历给她。刚开始我以为这家公司是创新工场旗下的一家子公司,所以还比较感兴趣,因为创新工场的创始人是李开复。在高中我就读过李开复的自传,并且一直奉为我滴偶像。但是通过了解,这家公司只是有创新工场的投资,而非它的子公司,属于创业型的小公司,规模在20人以下,而我想去的是大公司,所以没什么太大的兴趣了。不久,那边的技术面试官就打电话过来了,一点铺垫也没有,直接上来就是问技术问题,我都没反应过来,整个人还是懵的。他问了我一个问题:怎么优化ListView?刚开始我没明白ListView是什么?我说我没听清楚,然后他又重复了一遍,我是不懂,我说我不懂ListView是什么。然后他说怎么优化列表?这回我懂了,我是做IOS开发的,不太懂安卓开发,列表控件在安卓里面叫ListView,而在我们IOS开发中我们称之为TableView。我感觉这个面试官一点都不专业,再加上我对他们公司不太感兴趣,所以没有怎么认真的回答他,只是淡淡的说了一句,用下拉刷新,其实我没有回答到点子上,我应该说用列表重用机制的。回想一下,我还是不应该这么随便应付的,所以我决定还是要写篇博客详细总结写这个问题,这个问题还是比较好滴。


以前,写列表的时候,根本就没有列表重用概念,因为数据量很少,所以没用列表重用机制也没发现什么问题。但是在实际的项目开发中,当列表数据很多的时候,如果不用列表重用机制,就会导致列表滑动卡顿或者是列表数据重复等问题。这是因为

(1) iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万 个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象

(2)重⽤原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回 UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的 UITableViewCell,dataSource则会用新的数据来配置这个UITableViewCell,然后返回给 UITableView,重新显示到窗口中,从而避免创建新对象 。这样可以让创建的cell的数量维持在很低的水平,如果一个窗口中只能显示5个cell,那么cell重用之后,只需要创建6个cell就够了。

一、不用列表重用机制

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20) style:UITableViewStylePlain];
    tableView.delegate = self;
    tableView.dataSource = self;
    [self.view addSubview:tableView];
    
}

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

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"CELL";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }

    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 110, 70)];
    imageView.image = [UIImage imageNamed:@"image.jpg"];
    [cell addSubview:imageView];
    
    UILabel *labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(120, 0, 200, 25)];
    labelTitle.text = [NSString stringWithFormat:@"这是列表的第%ld条测试数据",(NSInteger)indexPath.row];
    [cell addSubview:labelTitle];
      return cell;
}

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


@end

不用列表重用机制,列表有多少条数据就会相应的创建多少个cell, 如果有一万条数据就会创建一万个cell,对内存而言会很耗内存,本身手机的内存又比较小,所以有时候真机测试的时候会出现列表滑动很卡的现象。另外,会导致列表界面数据重复或者混乱的现象,如下图所示:


IOS 列表重用机制_第1张图片

二、使用列表重用机制

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height-20) style:UITableViewStylePlain];
    tableView.delegate = self;
    tableView.dataSource = self;
    [self.view addSubview:tableView];
    
}

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

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"CELL";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
        
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 110, 70)];
        [imageView setTag:100];
        [cell.contentView addSubview:imageView];
        
         UILabel *labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(120, 0, 250, 25)];
        [labelTitle setTag:101];
        [cell.contentView addSubview:labelTitle];
    }

    UIImageView *imageView = (UIImageView*)[cell viewWithTag:100];
    imageView.image = [UIImage imageNamed:@"image.jpg"];
    
    UILabel *labelTitle = (UILabel*)[cell viewWithTag:101];
    labelTitle.text = [NSString stringWithFormat:@"这是列表的第%ld条测试数据",(NSInteger)indexPath.row];
    
    return cell;
}
 
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80;
}


@end

使用列表重用机制,列表会重复利用,不会不断的创建,可以极大的优化内存使用效率。如下图:
IOS 列表重用机制_第2张图片

OK,就这吧。

源代码下载地址 :http://download.csdn.net/detail/u010545480/8456291

你可能感兴趣的:(UITableView)