утечка памяти в ячейках iphone tableview? - PullRequest
0 голосов
/ 03 марта 2010

SO,

У меня есть табличное представление с 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];


}

Ответы [ 2 ]

1 голос
/ 03 марта 2010

Весь код вне цикла if (cell == nil) запускается для каждой видимой ячейки каждый раз, когда пользователь касается tableView. Попробуйте положить NSLog (@ "Я побежал!"); как раз перед return cell;

(код после возврата не будет запущен, т. Е. Все ваше освобождение памяти не выполняется)

Хорошо, вы делаете правильные вещи, используя теги views, чтобы вы могли ссылаться на них позже. Сделайте все вещи UILabel внутри цикла if (cell == nil), а затем вне цикла, прежде чем return cell используйте тег для установки значений меток:

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

Вот так.

Код в блоке if (cell == nil) запускается только в том случае, если ячейка ранее не отображалась, то есть все время находилась вне экрана и т. Д. Остальная часть кода выполняется все время при использовании tableView.

Надеюсь, это имеет смысл:)

0 голосов
/ 03 марта 2010

Попробуйте запустить с помощью инструмента «Утечки»

В Xcode нажмите «Выполнить»> «Выполнить с помощью Performance Tool»> «Утечки»

Любые утечки отображаются в виде красных линий, вы можете выбрать раздел на временной шкале, где были обнаружены утечки, и найти утечки, изучив стек. Если все это звучит немного сложно, тогда просто пошагово просматривая свой код и гарантируя, что вы выпускаете все, что создаете с помощью alloc, new, copy или их вариантов, вы должны обнаружить большинство потенциальных утечек.

Кстати, простая утечка не убьет ваше приложение так быстро, если оно не попадет в огромный цикл или что-то в этом роде

...