刷新UITableView的好方法

时间:2011-07-16 13:29:09

标签: iphone objective-c cocoa-touch uitableview

我想知道好的和内存有效的方法来重新加载对UITableView所做的所有更改。想象一下,如果您更改了笔记的日期/标题,Apple的原生笔记本应用程序会刷新UITableView。

当我将索引设置为显示内容的视图时,我确保重新加载我的索引数据

[indexTable reloadData];

现在唯一的问题是,如果之前使用的话,并不是每个单元都会被刷新,因为我在我的函数中有这个加载单元格:

//if (cell == nil) { // assign a label to them, e.g. the title of a note

    //} else {
    //   label = (UILabel *) [cell viewWithTag:1];
    //}

请参阅下面的整个代码。我现在真的想知道label = (UILabel *) [cell viewWithTag:1];位呢?我所知道的是,如果用户输入了一个新的音符标题,它不会刷新我的数据(尽管我调用indexTable重新加载!)。

我会像以下代码一样把它留在外面遇到严重的问题吗?

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

    static NSString *CellIdentifier = @"Cell";    
    UILabel *label;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    //NSLog(@"checking if cell is nil");

    //if (cell == nil) {

        NSLog(@"cell=nil");

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

        CGRect frame = CGRectMake(10, 0, 200, 30);
        label = [[UILabel alloc] initWithFrame:frame];
    label.lineBreakMode = UILineBreakModeTailTruncation;
        label.tag = 1;
    label.text = [[indexContent objectAtIndex:indexPath.row] itemTitle];

        [cell.contentView addSubview:label];
        [label release];

    //} else {
    //   label = (UILabel *) [cell viewWithTag:1];
    //}

    return cell;
}

非常感谢任何解释!

2 个答案:

答案 0 :(得分:1)

每当您滚动或重新加载tableview时,上面的代码将启动并为每个单元格分配内存。你应该使用

if (cell == nil) {
   NSLog(@"cell=nil");
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

因此,每次向下或向上滚动查看时,它都不会分配和创建新单元格。重新加载整个tableview的最佳方法是[tableview reloadData];据我所知。

希望得到这个帮助。

答案 1 :(得分:1)

您应该检查
的结果 [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; nil虽然没有这样做,但不会让你的应用崩溃,每次调用这个方法时你都会初始化/分配一个新的单元格,并且尝试重用一个单元格会更好(为什么尝试重新启动单元格,如果每次都分配/初始化一个新单元?) label = (UILabel *) [cell viewWithTag:1];没有做任何肯定的刷新,它只是在给定标记的情况下检索UILabel,它是单元格的子视图。在if部分中,您分配/初始化一个新单元,因为它是必需的,并配置其framelineBreakModetag属性并将其添加到单元格中。

因此,为了让您的内容更新(使用[tableView reloadData];),请在if / else序列之外提取UILabel内容设置部分,并切断其他部分:

if(cell == nil) {
    //init/alloc and configure a new cell
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];
    CGRect frame = CGRectMake(10, 0, 200, 30);
    label = [[UILabel alloc] initWithFrame:frame];
    label.lineBreakMode = UILineBreakModeTailTruncation;
    label.tag = 1;
    [cell.contentView addSubview:label];
    [label release];

}
// you either retrieved the cell, or just created it
// retrieve the label and update the content
label = (UILabel *) [cell viewWithTag:1];
label.text = [[indexContent objectAtIndex:indexPath.row] itemTitle];
return cell;