1. 程式人生 > >iOS開發之UI學習-UITableView的複用機制

iOS開發之UI學習-UITableView的複用機制

    最近編寫新功能的時候,偶然間發現有較少開發經驗的開發人員對於表檢視的單元格的複用問題並不是瞭解的很透徹,所以在此通過程式碼的形式快速的教給大家如何理解和運用單元格的複用問題。表檢視是在開發中經常使用的控制元件,而且有時處理的內容量也是非常巨大的,這就需要考慮表檢視的效能優化,而最基本的效能優化則是單元格的複用,正所謂基礎打得好,才能飛得高,所以需要很好的理解單元格是如何複用的。

    在表檢視顯示的時候,會建立 (檢視中可看的單元格個數+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

通過列印的地址我們可以看出複用:


兩種單元格的複用的方式存在著細微的差別,新手一般情況下會不太理解,但是隻要仔細觀看以上的程式碼,或者將程式碼直接貼上到新建立的工程中去,然後執行,可以得出和我截圖出的一樣的結果。希望以上程式碼能夠幫助對於表檢視的單元格複用不太理解的開發人群。當然這裡只是簡單的講解了一下單元格的重用機制,在實際的開發過程中,可能會因為不同的展示效果,需要合理的利用單元格的複用。