0

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

-(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)

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

有任何想法吗?

4

3 回答 3

2

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

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

之间(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 中对此进行了编码,如果有任何小的语法错误,我们深表歉意。

于 2013-02-01T00:15:54.690 回答
0

单元对象由第一条语句重用或创建。检查cellnil创建单元后,不得再创建另一个单元。

所以删除该行

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

紧随其后

NSUInteger row = [indexPath row];

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

于 2013-02-01T00:11:58.320 回答
0

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

我所做的是子类 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;
}

如果需要,我可以显示来自子类的更多代码。

于 2013-02-01T00:19:00.420 回答