#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 должно быть одинаковым во всем процессе.
Если он не соответствует, это приведет к ошибке индекса.