NSFetchedResultsController, возвращающий объекты с нулевым indexPaths
Подробности в комментариях.
Следующий код:
// Perform the fetch...
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
// Confirm that objects were fetched by counting them...
NSLog(@"Number of Objects = %i",
[[fetchedResultsController fetchedObjects] count]);
// Confirm that sections exist by counting them...
NSLog(@"Numbers of Sections = %i",
[[fetchedResultsController sections] count]);
for (id section in [fetchedResultsController sections]) {
// Count number of objects in each section
// _The fact that this outputs 0 is the first sign of trouble_
NSLog(@"Number of Objects in Section = %i", [section numberOfObjects]);
}
for (Reminder *reminder in [fetchedResultsController fetchedObjects]) {
// Confirm that the objects fetched are in fact real objects
// by accessing their "textContent" property...
NSLog(@"textContent=%@", reminder.textContent);
// Show that the fetched objects are being returned
// with a (null) indexPath...
// _The second sign of trouble..._
NSLog(@"IndexPath=%@",
[fetchedResultsController indexPathForObject:reminder]);
}
NSUInteger indexArr[] = {0,0};
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexArr
length:2];
// _Application crashes on this line because the fetched
// objects do not have indexPaths_
Reminder *testReminder = (Reminder *)[fetchedResultsController
objectAtIndexPath:indexPath];
NSLog(@"textContent = %@", testReminder.textContent);
Результаты в следующем выводе:
2010-07-17 00:48:41.865 Reminders[27335:207] Number of Objects = 3
2010-07-17 00:48:41.867 Reminders[27335:207] Numbers of Sections = 1
2010-07-17 00:48:41.868 Reminders[27335:207] Number of Objects in Section = 0
2010-07-17 00:48:41.870 Reminders[27335:207] textContent=Imported Object 3
2010-07-17 00:48:41.871 Reminders[27335:207] IndexPath=(null)
2010-07-17 00:48:41.873 Reminders[27335:207] textContent=Imported Object 2
2010-07-17 00:48:41.873 Reminders[27335:207] IndexPath=(null)
2010-07-17 00:48:41.874 Reminders[27335:207] textContent=Imported Object 1
2010-07-17 00:48:41.875 Reminders[27335:207] IndexPath=(null)
2010-07-17 00:48:41.887 Reminders[27335:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
Любые идеи очень приветствуются. К вашему сведению, приведенный выше код отлично работает в отдельном приложении, если я использую другой шаблон в качестве отправной точки. То есть если я использую шаблон «Window-based application», код потерпит неудачу. Если я использую «Приложение на основе навигации», код работает как положено.
Обновить: TechZen задавался вопросом, вызвана ли проблема моей сущностью Напоминания. Я подумал, что это хорошая идея для изучения, поэтому я сделал следующее:
Создайте два приложения-шаблона по умолчанию: «Приложение на основе окна» и «Приложение на основе навигации» (оба с включенными базовыми данными).
Копирование минимального кода, необходимого из Nav-based в Window-based для выполнения вышеуказанного теста (в основном только файл "xcdatamodel", контроллер fetchedresults и способ добавления тестовых объектов).
Приведенный выше код по-прежнему не работает в новом приложении на основе окна «Reminder-entity free». (В этом новом тестовом приложении фактически есть нулевой код, который я создал сам (за пределами тестового кода), это всего лишь код шаблона, вырезанный и вставленный вместе).
Итак, я ищутем не мение чтобы запустить приведенный выше код после создания «оконного приложения». Вот код для выполнения теста с использованием сущности по умолчанию на основе nav, на случай, если кто-то захочет попробовать:
ОБНОВИТЬ Обратите внимание, что, как TechZen отметил ниже, этот код будет зависать независимо от того, что будет работать с пустой базой данных, поэтому, если вы запускаете приложение из окна, сначала добавьте несколько объектов в базу данных, а затем добавьте тестовый код.
// Confirm that objects were fetched
NSLog(@"Number of Objects = %i",
[[fetchedResultsController fetchedObjects] count]);
// Confirm that sections exist
NSLog(@"Numbers of Sections = %i",
[[fetchedResultsController sections] count]);
for (id section in [fetchedResultsController sections]) {
// Count number of objects in sections
// _The fact that this outputs 0 is the first sign of trouble_
NSLog(@"Number of Objects in Section = %i", [section numberOfObjects]);
}
for (NSManagedObject *managedObject in [fetchedResultsController fetchedObjects]) {
// Confirm that the objects fetched are in fact real objects,
// by accessing their "timeStamp" property
NSLog(@"TimeStamp=%@", [[managedObject valueForKey:@"timeStamp"] description]);
// Show that the fetched objects are being returned
// with a (null) indexPath
// _The second sign of trouble..._
NSLog(@"IndexPath=%@",
[fetchedResultsController indexPathForObject:managedObject]);
}
NSUInteger indexArr[] = {0,0};
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:indexArr
length:2];
// _Application crashes on this line, because the fetched
// objects do not have indexPaths_
NSManagedObject *managedObject = [fetchedResultsController
objectAtIndexPath:indexPath];
NSLog(@"textContent = %@", [[managedObject valueForKey:@"timeStamp"] description]);
ОБНОВИТЬ здесь вывод при использовании нового вырезанного и вставленного кода
2010-07-18 15:33:41.264 Reminders[30898:207] Number of Objects = 3
2010-07-18 15:33:41.266 Reminders[30898:207] Numbers of Sections = 1
2010-07-18 15:33:41.267 Reminders[30898:207] Number of Objects in Section = 0
2010-07-18 15:33:41.270 Reminders[30898:207] TimeStamp=2010-07-18 13:59:00 -0400
2010-07-18 15:33:41.271 Reminders[30898:207] IndexPath=(null)
2010-07-18 15:33:41.272 Reminders[30898:207] TimeStamp=2010-07-18 13:59:00 -0400
2010-07-18 15:33:41.273 Reminders[30898:207] IndexPath=(null)
2010-07-18 15:33:41.274 Reminders[30898:207] TimeStamp=2010-07-18 13:58:59 -0400
2010-07-18 15:33:41.275 Reminders[30898:207] IndexPath=(null)
2010-07-18 15:33:41.276 Reminders[30898:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
ОБНОВИТЬ Таким образом, я сузил эту проблему до проблемы, связанной с версией SDK, у меня теперь есть проект, который, если я собираюсь с помощью Simulator 3.2, он падает, а сборка с помощью Simulator 3.1.3 работает нормально. НО, если я добавлю UITableViewController, затем соберусь с Simulator 3.2, тогда он снова будет работать нормально. Итак, я создалновый стекопоток пост, чтобы задать вопрос: если вы используете NSFetchedResultsController без UITableViewController, как вы взаимодействуете с объектами? (поскольку IndexPaths ненадежны).
ОБНОВИТЬ Эта проблема (предварительно) решена с помощью -[NSFetchedResultsController fetchedObjects] objectAtIndex:]
чтобы получить доступ к объектам.