重用UITableViewCell的问题

时间:2010-05-27 22:54:07

标签: iphone objective-c cocoa-touch uitableview

我有一个UITableView,当用户滚动时会重复使用单元格。所有内容都会显示并滚动正常,除非用户单击实际行,突出显示的单元格会显示另一个单元格中的某些文本。我不确定为什么。

#define IMAGE_TAG 1111
#define LOGIN_TAG 2222
#define FULL_NAME_TAG 3333

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    STUser *mySTUser = [[[STUser alloc]init]autorelease];
    mySTUser = [items objectAtIndex:indexPath.row];

    AsyncImageView* asyncImage = nil;
    UILabel* loginLabel = nil;
    UILabel* fullNameLabel = nil;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
    else {
        asyncImage = (AsyncImageView *) [cell.contentView viewWithTag:IMAGE_TAG];
        loginLabel = (UILabel *) [cell.contentView viewWithTag:LOGIN_TAG];
        fullNameLabel = (UILabel *) [cell.contentView viewWithTag:FULL_NAME_TAG];
    }

    // Configure the cell...

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    CGRect frame = CGRectMake(0, 0, 44, 44);
    asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
    asyncImage.tag = IMAGE_TAG;
    NSURL* url = [NSURL URLWithString:mySTUser.avatar_url_large];
    [asyncImage loadImageFromURL:url];
    [cell.contentView addSubview:asyncImage];

    loginLabel.tag = LOGIN_TAG;
    CGRect loginLabelFrame = CGRectMake(60, 0, 200, 10);
    loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
    loginLabel.text = [NSString stringWithFormat:@"%@",mySTUser.login];
    [cell.contentView addSubview:loginLabel];

    fullNameLabel.tag = FULL_NAME_TAG;
    CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 10);
    fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
    fullNameLabel.text = [NSString stringWithFormat:@"%@ %@",mySTUser.first_name, mySTUser.last_name]; //[NSString stringWithFormat:@"%@",mySTUser.login];
    [cell.contentView addSubview:fullNameLabel];    


    return cell;
}

2 个答案:

答案 0 :(得分:6)

此行分配一个对象然后丢弃它。不要分配你不会使用的项目。

STUser *mySTUser = [[[STUser alloc]init]autorelease];
mySTUser = [items objectAtIndex:indexPath.row];

相反,只需声明一个变量并使用它。

STUser *mySTUser;
mySTUser = [items objectAtIndex:indexPath.row];

这一行创建一个新对象并将其分配给单元格,但每次使用单元格时都会发生。

asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
[cell.contentView addSubview:asyncImage];

相反,将所有addSubview行放在创建单元格的if条件中。

if (cell == nil) {
    CGRect frame = CGRectMake(0, 0, 44, 44);
    CGRect loginLabelFrame = CGRectMake(60, 0, 200, 10);
    CGRect fullNameLabelFrame = CGRectMake(60, 20, 200, 10);
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
    [cell.contentView addSubview:asyncImage];
    loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
    [cell.contentView addSubview:loginLabel];
    fullNameLabel = [[[UILabel alloc] initWithFrame:fullNameLabelFrame] autorelease];
    [cell.contentView addSubview:fullNameLabel];    
    asyncImage.tag = IMAGE_TAG;
    loginLabel.tag = LOGIN_TAG;
    fullNameLabel.tag = FULL_NAME_TAG;
} else ...

唯一应该发生的事情就是if if block是对每个单元格更改的属性的赋值,例如[asyncImage loadImageFromURL:url];并将文本分配给标签。

此行为可能的nil对象分配属性,然后分配对象。

loginLabel.tag = LOGIN_TAG;
loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];

而是在创建对象后分配属性。

loginLabel = [[[UILabel alloc] initWithFrame:loginLabelFrame] autorelease];
loginLabel.tag = LOGIN_TAG;

此行使用格式化字符串,只需简单的赋值即可。

loginLabel.text = [NSString stringWithFormat:@"%@",mySTUser.login];

相反,假设mySTUser.login,只需直接指定它。

loginLabel.text = mySTUser.login;

答案 1 :(得分:0)

如果单元格不是nil,则首先从单元格中分配图像并标记变量,然后重新初始化它们。正确?