Jim Rhoades
Jim Rhoades

Reputation: 3320

Why do I get a memory leak when adding a button as a subview?

I have an app that uses a tableview, along with a UIButton that I add as a subview to each custom cell, like this:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    checkButton = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame:CGRectMake(2.0, 2.0, 40.0, 40.0)];
    [cell.contentView addSubview:checkButton];

    // lot's of other code

    return cell;
}

I thought all was fine until I started using Instruments to make sure I didn't have any memory leaks, but I've found that adding the UIButton as a subview of the cell like that somehow causes a leak within UIKit.

Specifically, I get a memory leak for each cell row (for each time the button is added as a subview), and the leaked object is "CALayer" with the responsible frame being "-[UIView _createLayerWithFrame:]".

Am I doing something wrong here?

Upvotes: 4

Views: 1915

Answers (3)

Daddy
Daddy

Reputation: 9035

The code [UIButton buttonWithType] method already includes an initWithFrame method. You need to just use a CGRectMake, and then set the frame of the button.

rectangle = CGRectMake(2.0f,2.0f,40.0f,40.0f);
checkButton = [UIButton buttonWithType:UIButtonTypeCustom];
checkButton.frame = rectangle;

Upvotes: 5

Lorenzo Boccaccia
Lorenzo Boccaccia

Reputation: 6131

Is checkButton a @property(retain) of your class?

Because in that case you should set the property to null after the usage... but you can't as the cell lifecycle of the cell is not under your control; you'll be better off with a local variable.

Also, you should put a [checkButton release] after the addSubview, as the addSubview code does it's own retain/release

Upvotes: 0

Ben S
Ben S

Reputation: 69342

Have you tested this on a physical device or on the simulator?

The simulator is known to have some memory management variations compared to the actual device code. You should always run memory leak tests on a real device.

Otherwise, your code looks correct to me.

Upvotes: 0

Related Questions