2010-03-02 2 views
0

SO,iphone tableview cell memory leak?

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


} 

ответ

1

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

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

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

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

как это.

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

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

0

Попробуйте запустить с помощью инструмента производительности 'Утечки'

В Xcode, выберите Run> Run с Performance Tool> ПРОТЕЧКАМ

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

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