Управление памятью в tableviewDataSource - PullRequest
0 голосов
/ 23 февраля 2011

Просто быстрый вопрос:

Я запускаю метод для извлечения записей из базы данных sqlite в массив, а затем присваиваю содержимое этого массива переменной экземпляра.

@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 release];

    return cell;

}

@end

У меня вопрос в два раза:

  1. Что я делаю, чтобы присвоить данные переменной экземпляра, верно? и я правильно управляю памятью?
  2. Как мне управлять памятью для этого элемента модели в источнике данных tableview? единственный способ заставить его работать гладко, если я вообще не освобождаю объект *model, но это, несомненно, вызывает утечки?

Приветствие.

Ответы [ 2 ]

2 голосов
/ 23 февраля 2011

Нет, здесь вы неправильно управляете памятью:

  • вам следует использовать «повторно используемые» UITableViewCells, большинство примеров UITableView показывают, как это сделать, и

  • не делайте [выпуск модели], в этом случае вы не «владеете» объектом, вы просто ссылаетесь на него, поэтому вы не должны отпускать его

Вот типичный 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;
}

Кроме того, если вы используете БД для своих данных, вы можете захотеть заглянуть в Core Data, инфраструктуру хранения / управления данными Apple, она включает в себя возможностьподключите аспекты ваших сущностей данных непосредственно к UITableViews.

0 голосов
/ 23 февраля 2011

1) Заполните метод правильно.Не забудьте установить для переменной экземпляра значение nil в dealloc.(Полагаю, вы добавили свойство / синтез, поскольку использовали 'self.').

2) НЕ освобождайте объект модели.Вы не сохранили, не скопировали или не распределили его таким способом.С другой стороны, ваша инициализация ячейки неверна.Используйте следующее: (лучше для производительности)

- (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
}
...