jj
jj

Reputation:

Why don't tablecells get released?

I simplified my code to test with, and still on the phone my memory usage keeps climbing to a point where the table slows way down.

Can someone tell me what I'm doing wrong here?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 40;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellID = @"Cell";
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
    }
    UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
    l.font=[UIFont boldSystemFontOfSize:15];
    l.textColor=[UIColor whiteColor];
    l.backgroundColor=[UIColor blackColor];
    l.text=@"Just some randoom text here";
    [cell.contentView addSubview:l];
    [l release];

Oops. That code paste didn't work too well. Here's a straight paste:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 40;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellID = @"Cell";
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
    }
    UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
    l.font=[UIFont boldSystemFontOfSize:15];
    l.textColor=[UIColor whiteColor];
    l.backgroundColor=[UIColor blackColor];
    l.text=@"Just some randoom text here";
    [cell.contentView addSubview:l];
    [l release];
        return cell;
}

Upvotes: 0

Views: 517

Answers (3)

RoelandVL
RoelandVL

Reputation:

Since every UITableViewCell has its own standard UILabel (cell.textLabel), do you really need that extra label added to the contentView? If you need custom cells, you might want to consider subclassing UITableViewCell.

Upvotes: 0

Jason
Jason

Reputation: 28600

You will want to follow a pattern like this:

#define kTagMyLabel 1

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
  static NSString *cellID = @"Cell1";
  UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
  UILabel * l;
  if (cell == nil) {
    // create the cell
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];

    // perform setup/functions that are common to all cells
    l = [[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)] autorelease];
    l.font=[UIFont boldSystemFontOfSize:15];
    l.textColor=[UIColor whiteColor];
    l.backgroundColor=[UIColor blackColor];
    l.tag = kTagMyLabel ;
    [cell.contentView addSubview:l];
  }
  else
  {
    // find the label we previously added.
    l = (UILabel*)[cell viewWithTag:kTagMyLabel];
  }

  // now set up the cell specific to this indexPath
  l.text=@"Just some random text here";
  return cell;
}

Upvotes: 1

drvdijk
drvdijk

Reputation: 5554

You're recycling UITableViewCell instances, but you're still creating a new UILabel instance for every row, and adding it to each and every cell. This is where the memory usage comes from. Try something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellID = @"Cell";
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease];
        UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)];
        l.font=[UIFont boldSystemFontOfSize:15];
        l.textColor=[UIColor whiteColor];
        l.backgroundColor=[UIColor blackColor];
        l.text=@"Just some randoom text here";
        [cell.contentView addSubview:l];
        [l release];
    }
    return cell;
}

Upvotes: 0

Related Questions