Monday, February 21, 2011

Why do these UITableViewCells cause a leak in instruments?

So after a lot of old fashioned comment-out-debugging to narrow down a leak in instruments. The leak occurs when I push a new TableViewController onto the stack.

I found that I'm getting a leak from this code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}

if(![feedData isFinishedLoading]){
 [[cell textLabel] setText:@"Loading..."];
 [[cell detailTextLabel] setText:@"..."];
}
else{
 NSDictionary *dict = [[feedData items] objectAtIndex:indexPath.row];
 [[cell textLabel] setText:[dict valueForKey:@"title"]];
 [[cell detailTextLabel] setText:[dict valueForKey:@"description"]];
 [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
}
return cell;
}

This version doesn't leak:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}

//  if(![feedData isFinishedLoading]){
//   [[cell textLabel] setText:@"Loading..."];
//   [[cell detailTextLabel] setText:@"..."];
//  }
//  else{
//   NSDictionary *dict = [[feedData items] objectAtIndex:indexPath.row];
//   [[cell textLabel] setText:[dict valueForKey:@"title"]];
//   [[cell detailTextLabel] setText:[dict valueForKey:@"description"]];
//   [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
//  }
return cell;
}

This version does:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}

//  if(![feedData isFinishedLoading]){
     [[cell textLabel] setText:@"Loading..."];
     [[cell detailTextLabel] setText:@"..."];
//  }
//  else{
//   NSDictionary *dict = [[feedData items] objectAtIndex:indexPath.row];
//   [[cell textLabel] setText:[dict valueForKey:@"title"]];
//   [[cell detailTextLabel] setText:[dict valueForKey:@"description"]];
//   [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
//  }
return cell;
}

Here's a screen cap of instruments: http://imgur.com/YR8k8

Is the problem in my code somewhere? Or is it a bug in the framework/simulator?

From stackoverflow
  • There is nothing in that leak stack that calls your code so I don't know if you can get rid of it. I know a Big red spike is scary, but it is only 16 bytes. Apple is not perfect and perhaps something in their code is doing it. Maybe you can try using the dot accessors to see if that helps

    cell.textLabel.text = @"Loading...";
    cell.detailTextLabel.ext = @"...";
    

0 comments:

Post a Comment