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を使い始めたときとまったく同じことをしました。メモリリークの理由は、2番目の実装(機能する実装)では、実際にはすべてのセルを毎回作成しているためです。もう少し説明させてください。

セルの内容をの間に設定する必要はありません(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

テーブルビューがセルを再利用する場合、それは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 に答える
0

cell オブジェクトは、最初のステートメントによって再利用または作成されます。セルを確認cellnilて作成した後は、別のセルを作成しないでください。

だから行を削除する

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

後に来るもの

NSUInteger row = [indexPath row];

正しいセル オブジェクトを操作します。

于 2013-02-01T00:11:58.320 に答える