开发者

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:

  1. Is what i'm doing to assign data to the instance variable right? and am i managing the memory correctly?
  2. 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
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜