iphone: основные данные: сбой NSManagedObjects и UITableView

#iphone #uitableview #core-data #nsmanagedobject

#iPhone #uitableview #основные данные #nsmanagedobject

Вопрос:

Этот метод выборки работает отлично, и NSLog распечатывает содержимое базы данных … (извлеченные объекты в NSArray):

 NSError *error2;
fetchedObjects = [moc executeFetchRequest:fetchRequest error:amp;error2];

if (!fetchedObjects) {
    NSLog(@"Error %@",[error2 localizedDescription]);
}

for (NSManagedObject *info in fetchedObjects) {

    NSLog(@"Name: %@", [info valueForKey:@"Name"]);
    NSLog(@"Description: %@", [info valueForKey:@"Description"]);
    NSLog(@"Ingredients: %@", [info valueForKey:@"Ingredients"]);
  

.. но когда я пытаюсь заполнить TableView (я создал много таблиц и чувствую, что хорошо понимаю, как они работают), программа завершает работу с «EXE_BAD_ACCESS at int retVal = UIApplicationMain (argc, argv, nil, nil);». Вот и все, никаких других сообщений об ошибках.

Чтобы попытаться выполнить отладку, я ввел этот простой NSLog в метод «cellForRowAtIndexPath», но он вылетает при NSLog (@»Количество выбранных объектов в tableview %i», [Количество выбранных объектов]).

Насколько я могу судить, я не выпустил массив.

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    NSLog(@"fetchedObjects count in tableview %i",[fetchedObjects count]);
    NSManagedObject *info3 = [fetchedObjects objectAtIndex:indexPath.row];
    NSLog(@"Name: %@", [info3 valueForKey:@"Name"]);
    cell.textLabel.text = [info3 valueForKey:@"Name"];
  

Комментарии:

1. Сколько строк подсчитывается в вашем numberOfRowsInSection? каким методом вы инициализируете извлеченные объекты?

2. Привет, Правин. Я использую return [ArrayNameHere count]; В настоящее время 27. Что означает, что массив существует …!?!

Ответ №1:

Похоже, что ваша fetchedObjects переменная экземпляра освобождается из-за сброса пула автозапуска.

NSManagedObjectContext -executeFetchRequest:error: метод возвращает автоматически выпущенный NSArray экземпляр, на который вы не получаете права собственности, поэтому к моменту выполнения -tableView:cellForRowAtIndexPath: метода пул автоматического выпуска был сброшен, и этот объект освобожден, и теперь у вас есть висячий указатель. Ах, классика.

Решение, конечно, состоит в том, чтобы отправить -retain сообщение, возвращенное NSArray после отправки -executeFetchRequest:error: вашему NSManagedObjectContext .

Не забудьте отправить ему -release сообщение своим -dealloc методом.

Комментарии:

1. Спасибо, Джейкоб. Я скопировал fetchObjects в другой массив: displayArray = [NSArray arrayWithArray:fetchedObjects]; и распечатал содержимое (все в порядке). Я проверяю массив непосредственно перед вызовом таблицы reloaddata [Количество отображаемых массивов], которая тоже отлично работает. Изменил TableView, чтобы указать на этот новый массив, и он по-прежнему выходит из строя в NSLog ` NSLog(@»Количество отображаемых массивов в tableview %i», [Количество отображаемых массивов]);` Я даже создал другой массив вручную и указал TableView на это, чтобы убедиться, что таблица работает (и это так). Я также несколько раз очищал проект на всякий случай.

2. Наконец-то все заработало. Я должен был скопировать fetchedObjects в новый массив, поэтому: displayArray = [fetchedObjects mutableCopy]; казалось бы, копирование массива с использованием [NSArray arrayWithArray:fetchedObjects] было неправильным. Спасибо за вашу помощь.

3. @Jeremy Создание копии намного дороже, чем простой вызов -retain . Вы действительно должны делать то, что я вам сказал, а не делать копию. Это ненужные накладные расходы.

Ответ №2:

Проблема, похоже, в этой строке

NSManagedObject *info3 = [Извлеченный объект objectAtIndex:indexPath.row];

Попробуйте использовать

NSManagedObject *info3 = [fetchedObjects objectAtIndex:0];

Потому что количество ваших UITableViewCell и fetchedObjects должно быть одинаковым во всем процессе.

Если он не соответствует, это приведет к ошибке индекса.