Reputation: 8327
I get a memory leak in cellForRowAtIndexPath, in a new application, with ARC enabled. The cellForRowAtIndexPath displays just a UILabel. Buf it I add [myUIlabel release]; I get ARC error: "ARC forbids explicit message send of 'release'"
Leak goes away if I remove the UILabel.
I don't want to disable ARC because it makes memory 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;
}
Upvotes: 0
Views: 1828
Reputation: 199
you are allocating and adding index_label to each cell every time.so it is increasing memory every time. 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.
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;
}
Upvotes: 2
Reputation: 5893
You are adding the index_label
subview to each cell EVERY TIME you dequeue a cell. 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. Which one of these options is appropriate depends on how you've written your app; personally I use storyboards with prototype cells.
Upvotes: 2