简体   繁体   English

使用ARC的cellForRowAtIndexPath中的内存泄漏

[英]memory leak in cellForRowAtIndexPath with ARC

I get a memory leak in cellForRowAtIndexPath, in a new application, with ARC enabled. 在启用了ARC的新应用程序中,cellForRowAtIndexPath中出现内存泄漏。 The cellForRowAtIndexPath displays just a UILabel. cellForRowAtIndexPath仅显示一个UILabel。 Buf it I add [myUIlabel release]; 我添加了[myUIlabel版本]; I get ARC error: "ARC forbids explicit message send of 'release'" 我收到ARC错误:“ ARC禁止显式发送'release'消息”

Leak goes away if I remove the UILabel. 如果我删除UILabel,泄漏将消失。

I don't want to disable ARC because it makes memory mgmt. 我不想禁用ARC,因为它会使内存成为mgmt。 easier. 更轻松。

What is the solution? 解决办法是什么?

HERE'S THE CODE... 这是代码...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    int   row = indexPath.row;
    float font_size;
    UITextView*  PWR_RX_cover_box;
    int x,y,w,h;

    // Determine which channel:
        int channel = tableView.tag;  // tag=channel, set at init time


    // Prepare to update cell:
        // DOCUMENTATION:  Table View Programming Guide for iOS > Adding subviews to a cell’s content view
        // Give each cell a cell identifier unique to each channel tableView and unique to each row, so that each gets a unique data structure:
        NSString *CellIdentifier = [NSString stringWithFormat:@"%d_%d",channel,indexPath.row];

        //static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            // if nil: cell(chan, row) has not been created before.  <>nil: cell = data structure previously initialized
        if (cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
        }

    // Erase anything previously displayed in the cell, by drawing cell-size big, white label:
        font_size = 10.0;
        // Top, left corner of cell:
            y = 0;  
            x = 0;
        // Entire area of cell:
            h = CHANNEL_ROW_HEIGHT;      // height of cell
            w = channel_tableView_width;   // width of cell
        UILabel* index_label = [[UILabel alloc] initWithFrame: CGRectMake( x,y, w,h)];
        index_label.backgroundColor = [UIColor whiteColor];
        index_label.textAlignment = NSTextAlignmentLeft; // NSTextAlignmentCenter, NSTextAlignmentLeft    NSTextAlignmentRight
        index_label.textColor=[UIColor darkGrayColor];
        index_label.numberOfLines=1;
        index_label.font = [UIFont systemFontOfSize: font_size];
        index_label.text = [NSString stringWithFormat:   @"" ];     
        //index_label.text = [NSString stringWithFormat:   @" *LAST %d *", ++last_ind];     //  normally ""
        [cell.contentView addSubview:index_label ];
        [index_label release];   <<<<<<<<<<<<<<<<<<<   CAUSES ARC COMPILE ERROR
         return cell; 

} }

You are adding the index_label subview to each cell EVERY TIME you dequeue a cell. 每次使一个单元出队时,都将index_label子视图添加到每个单元。 You will end up adding the label multiple times and increasing your memory usage; 您最终将多次添加标签并增加了内存使用量。 however, this is not a memory leak but a problem in your logic. 但是,这不是内存泄漏,而是您的逻辑问题。 The memory will be reclaimed when the cell is destroyed. 销毁单元后,将回收内存。

The solution is simple: Create your UILabel in your cell XIB , Prototype Cell or inside the cell == nil code section. 解决方案很简单:在cell XIBPrototype Cellcell == nil代码部分内创建UILabel Which one of these options is appropriate depends on how you've written your app; 这些选项中的哪一个合适,取决于您编写应用程序的方式。 personally I use storyboards with prototype cells. 我个人使用带有原型单元的情节提要。

you are allocating and adding index_label to each cell every time.so it is increasing memory every time. 您每次都会在每个单元格中分配和添加index_label,因此每次都会增加内存。 you can create index_label in (cell == nil) block and assign some tag to index_label to access the label each time to update properties of index_label. 您可以在(cell == nil)块中创建index_label,并为index_label分配一些标签以每次访问标签以更新index_label的属性。

solution : 解决方案

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    int   row = indexPath.row;
    float font_size;
    UITextView*  PWR_RX_cover_box;
    int x,y,w,h;

    // Determine which channel:
    int channel = tableView.tag;  // tag=channel, set at init time


    // Prepare to update cell:
    // DOCUMENTATION:  Table View Programming Guide for iOS > Adding subviews to a cell’s content view
    // Give each cell a cell identifier unique to each channel tableView and unique to each row, so that each gets a unique data structure:
    NSString *CellIdentifier = [NSString stringWithFormat:@"%d_%d",channel,indexPath.row];

    //static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    // if nil: cell(chan, row) has not been created before.  <>nil: cell = data structure previously initialized
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];

        UILabel* index_label = [[UILabel alloc] initWithFrame: CGRectZero];
        index_label.backgroundColor = [UIColor whiteColor];
        index_label.textAlignment = NSTextAlignmentLeft; // NSTextAlignmentCenter, NSTextAlignmentLeft    NSTextAlignmentRight
        index_label.textColor=[UIColor darkGrayColor];
        index_label.numberOfLines=1;
        index_label.font = [UIFont systemFontOfSize: font_size];
           [cell.contentView addSubview:index_label ];
        index_label.tag=TAG_VALUE;
    }

    // Erase anything previously displayed in the cell, by drawing cell-size big, white label:
    font_size = 10.0;
    // Top, left corner of cell:
    y = 0;
    x = 0;
    // Entire area of cell:
    h = CHANNEL_ROW_HEIGHT;      // height of cell
    w = channel_tableView_width;   // width of cell

    UILabel* index_label=[cell.contentView viewWithTag:TAG_VALUE];
    index_label.text = [NSString stringWithFormat:   @"" ];
    index_label.frame=CGRectMake( x,y, w,h);
    return cell;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM