0

それで、

テキストタイトル、サブタイトルラベル、テキストフィールド(背景を美しくするためのボタン付き)を持つ20個のセルを持つテーブルビューがありますが、テーブルビューを数回スクロールした後、シミュレーターで速度が低下し始めることがわかりました. これはメモリリークだと思いますが、必要なものはすべて解放したと思っていました。私の(アマチュア)コードに関するコメントはありますか?

注: 以前、Quartz で角丸を使用してテキストビューの周りにボックスを描画しようとしましたが、ボックスのスクロールも劇的に遅くなりました。私のコードを破棄する前に、メモリ リークを調べてください ;P

注 2: PS コードをリベラルにして申し訳ありませんが、リークが見つかりません。

よろしく

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


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        CGRect frame; frame.origin.x = 5; frame.origin.y = 10; frame.size.width = 20; frame.size.height = 25; 

        //Disallow Selection (Blue Flash)
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        //Print Icon
        UIImageView *imgLabel = [[UIImageView alloc] initWithFrame:frame];
        imgLabel.tag = 1;
        [cell.contentView addSubview:imgLabel];
        [imgLabel release];

        //Print Text
        frame.origin.x = 30; 
        frame.origin.y = 5;
        frame.size.width = CONST_Cell_width;    
        UILabel *nameLabel = [[UILabel alloc] initWithFrame:frame];
        nameLabel.tag = 100;
        [cell.contentView addSubview:nameLabel];
        [nameLabel release];

        //subtitleLabel Text
        UILabel *subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 32, CONST_Cell_width, 40)];
        subtitleLabel.tag = 101;
        [cell.contentView addSubview:subtitleLabel];
        [subtitleLabel release];



//      detailLabel.layer.cornerRadius = 10;


    } 
    //This bit is good!
    //cell.textLabel.text         = [[contentArray objectAtIndex:indexPath.row] objectForKey:@"Title"];
    //cell.detailTextLabel.text = [[contentArray objectAtIndex:indexPath.row] objectForKey:@"Description"];
    //Sets wrapping correctly
    //cell.textLabel.numberOfLines = 0;
    //cell.detailTextLabel.numberOfLines = 0;



    //Setup Name to Cell
    UILabel * nameLabel = (UILabel *) [cell.contentView viewWithTag:100];
    [nameLabel setFont:[UIFont boldSystemFontOfSize:20.0]];
    nameLabel.text = [[contentArray objectAtIndex:indexPath.row] objectForKey:@"Title"];
    nameLabel.textColor = [UIColor blackColor];
    nameLabel.backgroundColor = [UIColor clearColor];
    nameLabel.numberOfLines = 1;

    //Setup Subtitle
    UILabel * subtitleLabel = (UILabel *) [cell.contentView viewWithTag:101];
    [subtitleLabel setFont:[UIFont systemFontOfSize:15.0]];
    subtitleLabel.textColor = [UIColor grayColor];
    subtitleLabel.text = [[contentArray objectAtIndex:indexPath.row] objectForKey:@"Description"];
    subtitleLabel.backgroundColor = [UIColor clearColor];
    subtitleLabel.numberOfLines = 2;


        //A Nice Button for rounded background effect..cheap i know
        UIButton *roundedButtonType = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
        roundedButtonType.frame = CGRectMake(30, 80, CONST_Cell_width, CONST_Text_height);
        roundedButtonType.userInteractionEnabled = NO;
        roundedButtonType.backgroundColor = [UIColor clearColor];
        [cell.contentView addSubview:roundedButtonType];
        [roundedButtonType release];

        UITextView *detailLabel = [[UITextView alloc] initWithFrame:CGRectMake(30, 80, CONST_Cell_width, CONST_Text_height)];
        detailLabel.tag = indexPath.row;
        detailLabel.backgroundColor = [UIColor clearColor];
        detailLabel.text = [NSString  stringWithFormat:@"%d",indexPath.row];
        detailLabel.font = [UIFont fontWithName:@"Helvetica" size:17];
        detailLabel.delegate = self;
        [cell.contentView addSubview:detailLabel];
        [detailLabel release];

        //NSLog(@"Made my way to cellForRowAtIndexPath. Enter some data!!!\n");
        //DataPoint Name
        NSString *keyname = [NSString stringWithFormat:@"data%d",indexPath.row +1];
        NSString *datavalue = [clientDataArray objectForKey:keyname];

        //DataValue (can be null)
        //NSString *dataValue = [clientDataArray objectForKey:keyname] ;
    if (datavalue == [NSNull null] ) datavalue = @"(blank)";



    detailLabel.text = datavalue;



    return cell;
    [datavalue release];
    [keyname release];
    [clientDataArray release];


}
4

2 に答える 2

1

if(cell == nil) ループの外側のすべてのコードは、ユーザーが tableView に触れるたびに、すべての可視セルに対して実行されます。NSLog(@"I ran!"); を入れてみてください。直前return cell;

(リターン後のコードは実行されません。つまり、メモリの解放はすべて行われていません)

ビュータグを指定して正しいことを行っているので、後でそれらを参照できます。return cellタグを使用してラベルの値を設定する前に、if(cell == nil) ループ内でもすべての UILabel を実行し、次にループ外で実行します。

((UILabel *)[cell viewWithTag:14]).text = [myDataArray objectAtIndex:indexPath.row];

このような。

if(cell==nil) ブロックのコードは、セルが以前に表示されていない場合、つまりずっと画面外にあった場合などにのみ実行されます。コードの残りの部分は、tableView を使用するときに常に実行されます。

それが理にかなっていることを願っています:)

于 2010-03-02T23:17:25.957 に答える
0

パフォーマンスツール「Leaks」で実行してみる

Xcode で、[実行] > [パフォーマンス ツールで実行] > [リーク] をクリックします。

リークは赤い線で表示されます。リークが検出されたタイムライン上のセクションを選択し、スタックを調べることでリークを見つけることができます。それが少し複雑に聞こえる場合は、コードをステップ実行して、alloc、new、copy、またはそれらのバリアントで作成したものをすべてリリースしていることを確認するだけで、ほとんどの潜在的なリークを検出できます。

ところで、巨大なループなどに陥らない限り、単純なリークでアプリがすぐに停止することはありません。

于 2010-03-02T23:06:56.920 に答える