iOS tableView单元缓存问题没有加载每个单元格

时间:2013-01-31 23:58:08

标签: ios objective-c xcode tableview cell

我很难理解出了什么问题以及如何解决这个问题。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


    NSUInteger row = [indexPath row];

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

    UILabel *where = [[UILabel alloc] initWithFrame:CGRectMake(88.0, 0.0, 155.0, 22.0)];
    where.text = [delegate.destinationArray1 objectAtIndex:row];
    where.font = [UIFont fontWithName:@"Helvetica" size:12.0];
    where.textColor = [UIColor blueColor];
    [cell.contentView addSubview:where];
    return cell;
}

这不能正常工作,但确实如此:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

NSUInteger row = [indexPath row];

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

    UILabel *where = [[UILabel alloc] initWithFrame:CGRectMake(88.0, 0.0, 155.0, 22.0)];
    where.text = [delegate.destinationArray1 objectAtIndex:row];
    where.font = [UIFont fontWithName:@"Helvetica" size:12.0];
    where.textColor = [UIColor blueColor];
    [cell.contentView addSubview:where];
    return cell;
}

它们都被“delegate.destinationArray1”填充,但当所有代码都在

的大括号内时
if(cell == nil)

列表无序并重复单元格并错过了一些单元格。我无法使用后一种方式,因为它在滚动时会产生大量内存泄漏。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

当我开始使用UITableViews时,我做了同样的事情。内存泄漏的原因在于,在第二个实现(有效的实现)中,您实际上每次创建每个单元。让我试着解释一下。

您永远不想在(cell == nil)之间设置单元格的内容。原因是reuseIdentifier。如果表需要显示一个新单元格,它将抓取一个并查看它是否已被分配/输入。如果有,它只会使用它。如果是这种情况,内容将已经在您抓取的单元格中设置,并且您没有告诉它以不同的方式设置它。

{p}之间只有(cell == nil)创建并建立视图。不是内容。所有内容都应该在之后设置。那么无论它抓住什么单元格,它总能设置内容。所以这就是你想要的:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier = @"Cell";

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if(!cell) // or (cell == nil)
     {
          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
          cell.selectionStyle = UITableViewCellSelectionStyleBlue;
          UILabel *where = [[UILabel alloc] initWithFrame:CGRectMake(88.0, 0.0, 155.0, 22.0)];
          where.font = [UIFont fontWithName:@"Helvetica" size:12.0];
          where.textColor = [UIColor blueColor];
          where.tag = 1;
          [cell addSubview:where];
     }

     NSUInteger row = indexPath.row;

     UILabel *where = [cell viewWithTag:1];
     where.text = [delegate.destinationArray1 objectAtIndex:row];

     return cell;
}

我刚刚在StackoverFlow中对此进行了编码,很抱歉,如果语法错误很少。

答案 1 :(得分:0)

第一个语句重用或创建单元格对象。检查cell nil并创建单元格后,您不能创建另一个单元格。

所以删除行

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

之后的

NSUInteger row = [indexPath row];

您将使用正确的单元格对象。

答案 2 :(得分:0)

当tableview重用单元格时,它基于CellIdentifier。 tableview不关心你在单元格上设置了什么属性。在第一种情况下,重复它发生并且它识别它可以使用的单元但是该单元具有错误的信息。

我所做的是UITableViewCell的子类,并完成该类内部的所有工作。这是一个快速代码段

@implementation AlertCell

//Custom init method
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withHeight:(float)height {
//Whatever you need to do
}

//Place the views
- (void)layoutSubviews {
}

//Custom Setter method
- (void)setAlert:(CWAlert *)incomingAlert withAssets:(NSDictionary *)assets {
}

@end

然后你做这样的事情

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier;
CWAlertCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

if (!cell) {
    cell = [[AlertCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier withHeight:[self convertAssetsLengthToCellHeight:assetsLength]];

    UIView *selectedView = [[UIView alloc] init];
    selectedView.backgroundColor = [UIColor colorWithHexString:@"F6F6F6"];
    cell.selectedBackgroundView = selectedView;
}

NSDictionary *alertInfo = [AlertCell getNeededCellAssets:alert];
[cell setAlert:alert withAssets:alertInfo];
return cell;
}

如果需要,我可以从子类中显示更多代码。