有效地自定义简单的UITableViewCell

时间:2015-03-29 19:20:31

标签: ios uitableview tableviewcell memory-efficient

我想自定义一个简单的 UITableViewCell ,以便我只运行一次自定义并稍后添加值(例如,单元格标题)。我的应用程序的单元格更复杂 - 它有子视图并使用自动布局;但是,我相信一个简单的例子将有助于关注目标。

我正在使用iOS 8,Xcode 6.X,Objective-C和Nibs(没有故事板)来保持简单。我还没有为 UITableViewCell 创建自定义类。相反,我有以下代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    //[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;  //FIXED VALUE FOR EXAMPLE'S SAKE
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;  //FIXED VALUE FOR EXAMPLE'S SAKE
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"tableView:cellForRowAtIndexPath:");

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell == nil) {

        NSLog(@"cell == nil");

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        //CUSTOMIZING CELL THAT I WANT TO RUN ONLY ONCE
        cell.backgroundColor = [UIColor redColor];
    }

    NSArray *numbersArray = @[@1,@2,@3];
    cell.textLabel.text = [NSString stringWithFormat:@"%@", numbersArray[indexPath.row]];

    return cell;
}

哪个输出:

tableView:cellForRowAtIndexPath:
cell == nil
tableView:cellForRowAtIndexPath:
cell == nil
tableView:cellForRowAtIndexPath:
cell == nil

第一个问题:为什么cell == nil会运行3次?运行自定义代码cell.backgroundColor = [UIColor redColor]; 3次似乎很浪费。

现在,当我启用时:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

并使用:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

而不是:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

我得到了输出:

tableView:cellForRowAtIndexPath:
tableView:cellForRowAtIndexPath:
tableView:cellForRowAtIndexPath:

第二个问题:为什么cell == nil根本没有运行?

最终问题:如何让cell == nil只运行一次,以便只格式化UITableViewCell一次?有没有更好的方法来定制一个简单的单元格,只运行一次自定义代码?

2 个答案:

答案 0 :(得分:3)

  

为什么cell == nil运行3次?运行自定义代码cell.backgroundColor = [UIColor redColor]; 3次。

表格视图最有可能同时显示三个单元格,因此需要三个不同的单元格对象。

  

为什么不是单元格== nil运行?

文档指出,如果您之前注册了标识符,-dequeueReusableCellWithIdentifier:forIndexPath:将始终返回有效的单元格。它基本上负责检查是否需要新的单元格。

  

如何让cell == nil只运行一次,以便只格式化UITableViewCell一次?

你没有。您必须自定义每个实例。我建议使用自定义子类,而不是从外部弄乱UITableViewCell

答案 1 :(得分:1)

执行此操作的最佳方法是为您的单元格创建自定义类,并执行任何不依赖于indexPath的自定义。通常,我会在initWithCoderawakeFromNib中执行此操作。你应该在viewDidLoad注册nib;除非文件名错误,否则我在您对Christian的答案的评论中提到的代码没有任何问题。添加子视图或自定义单元格确实不是视图控制器的业务;该代码属于单元格的类。

顺便说一句,这并不会使自定义代码多次运行。它需要为您创建的每个单元实例运行一次,就像在原始代码中一样。创建的单元格数量将等于一次适合屏幕的数量(可能加一)。