views:

628

answers:

2

I have a memory leak that displays UICachedDeviceWhiteColor. I'm not using UICachedDeviceWhiteColor anywhere and a search on it turns up people saying this is a bug in the iPhone-SDK. I found this blog entry: http://piezoelectrics.blogspot.com/2009/02/uicacheddevicewhitecolor-leak-in-iphone.html

but I can't find

#import "NSAutoreleasePool.h"

I get an "error: NSAutoReleasePool.h: no such file or directory". Is there a fix for this memory leak or a correct way to allocate table cells from nibs?

Here's how I'm currently doing it:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {   

UITableViewCell *cell = nil; 
cell = [tableView dequeueReusableCellWithIdentifier:@"CellNameIdentifier"];

if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"CellName" owner:self options:nil];
//cellName is IBOutlet to XIB's tablecell.  I reference it several times in this calss
cell = cellName; 
}

return cell;

}

I don't see an alloc here so why would there be a mem leak? Could this be a problem:

@property (nonatomic, retain) IBOutlet UITableViewCell *cellName;
+1  A: 

Because of your property declaration, the sythesized setter for your cellName property will retain the object passed to it.

You should send a release message to cellName in your dealloc method.

Furthermore, there is no need to load the nib every time the cellView is requested. Either check if cellName != nil and return it or set the reuseIdentifier on the cellView so that it can be found by dequeueReusableCellWithIdentifier.

VoidPointer
+1  A: 

Actually, if you're using a NIB for your table view cell (not normally necessary unless you're doing something really custom) you will have to load it each time you didn't get a hit on the reusable table view cell. I think the following code looks a bit cleaner:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyID"];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CellName"
                    owner:self options:nil];
    cell = [nib objectAtIndex:1];
}

The objectAtIndex:1 trick works if the cell is the first object in the NIB (the zero object is the file owner).

Some notes for doing table view cells:

  • Don't retain your cell objects either implicitly by assigning to a property or manually. This will make the the reusable table cell functionality not work properly since it can't free the cell memory.
  • Don't forget to set the cell reuse identifier in interface builder since you can't do it in code if you're using a NIB.
  • Always make sure the cell is autoreleased. Either do it manually, or ensure you're using a cocoa function that returns autoreleased memory (as the objectAtIndex: method does).
Jon Thomason
For #1, would the property attributes only contain 'nonatomic'? For #3, where is the cell autoreleased...dealloc - but that isn't what you mean right?
4thSpace
I can't elaborate in a comment (too short). It sounds like you need to read the objective-C memory management paper. Make sure you get a firm grasp of reference counts and retain, release, and dealloc. There's also a section on autorelease. Send me mail at [email protected] if I can help.
Jon Thomason