Memory Management in tableviewDataSource
Just a quick question really:
I'm running a method to pull records from an sqlite database into an array, then assigning the contents of that array to an instance variable.
@interface {
NSArray *items;
}
@implementation
// The population method.
-(void)populateInstanceVariable
{
NSMutableArray *itemsFromDatabase = [[NSMutableArray alloc] init];
// Sqlite code here, instantiating a model class, assigning values to the instance variables, and adding this to the itemsFromDatabase Array.
self.items = itemsFromDatabase;
[itemsFromDatabase release];
}
// viewDidLoad is calling the method above
-(void)viewDidLoad
{
[self populateInstanceVariable];
[super viewDidLoad];
}
// TableViewDataSource method - cellforIndexPath
- (UITableViewCell *)tableView:(UITableView *)passedInTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault];
// Load in my model from the instance variable - ***1
MyDataModel *model = [items objectAtIndexPath:indexPath.row];
// Assign the title to the cell from the model data
cell.textLabel.text = model.title;
// This is the part i'm stuck on, releasing here causes a crash!
[model relea开发者_运维知识库se];
return cell;
}
@end
My question is two fold:
- Is what i'm doing to assign data to the instance variable right? and am i managing the memory correctly?
- How do i manage the memory for that model item in the tableview datasource? the only way i seem to be able to get it to run smoothly is if i don't release the
*model
object at all, but that causes leaks surely?
Cheers.
No, you're not managing memory correctly here:
you should use "reusable" UITableViewCells, most UITableView examples show how to do this, and
do not do [model release], you do not "own" the object in this case, you're just referring to it so you must not release it
Here's the typical cellForRowAtIndexPath:
-(UITableViewCell *) tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
// settings that do not change with every row
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
// settings that change with every row
cell.textLabel.text = @"fill in your label here";
return cell;
}
Also, if you're using a DB for your data, you may want to look in to Core Data, Apple's data persistence/management framework, it includes the ability to hook aspects of your data entities directly up to UITableViews.
1) Populate method is correct. Don't forget to set the instance variable to nil in the dealloc. (I suppose you added a property/synthesize as you used the 'self.').
2) Do NOT release the model object. You did not retain, copy or allocated it in that method. By the other hand your initialization of the cell is wrong. Use the following: (Better for performance)
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *Identifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:Identifier] autorelease];
}
//Other code
}
精彩评论