NSFetchResultsController с NSPredicate (отношение) против базового NSFetchRequest (изображение включено)
Вот изображение отношений, которые я обсуждаю:
У меня есть установка UIScrollView в качестве горизонтальной прокрутки, которая прокручивает между 3 различными UIViewControllers (содержащие, конечно, UITableView и необходимые методы делегата и т. Д.)
Каждый ViewController в UIScrollView загружает UITableView определенного MyObjectType.
(Например, ViewController1 загружает табличное представление всех объектов MyObject, где его тип == MyObjectType.name)
Имеет ли это смысл? Вы заметите, что я установил обратную связь между объектами. MyObjectType может иметь много MyObject, но MyObject может иметь только один MyObjectType, связанный с ним.
Когда я впервые загружаю один из viewController UIScrollView, мне нужно определить, для чего предназначен MyObjectType этот UITableView. У меня это работает нормально, и я соответственно установил заголовок таблицы.
Например [type valueForKey:@"name"]
где тип - это выбранный результат NSManagedObject объекта MyObjectType.
Дело в том, что мне интересно, когда я получаю этот NSManagedObject MyObjectType, я не имею также доступа к массиву NSSet * (т.е. [type valueForKey:@"objects"]
) который я могу использовать в качестве источника данных UITableView? Будет ли это работать, если после добавления или удаления объекта я сохраняю управляемый текст, а затем всегда [tableView reloadData]
?
Я предполагаю, что это будет работать, если мне не требуется, чтобы содержимое UITableView изменялось и обновлялось динамически при добавлении нового MyObject этого типа? Для этого нам нужен NSFetchedResultsController, верно?
Вот мой код для загрузки ВСЕХ MyObject-ов в UITableView (который работает):
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"MyObject" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"creationDate" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext sectionNameKeyPath:@"transientSectionDate"
cacheName:@"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
[sort release];
[fetchRequest release];
[theFetchedResultsController release];
return _fetchedResultsController;
}
Может ли кто-то ПОЖАЛУЙСТА быть настолько любезным, чтобы показать мое, какое фактическое объявление NSPredicate мне нужно для корректной загрузки ТОЛЬКО MyObject, чей MyObjectType.name == @ "XXXXXX"? Предположим, у меня уже есть MyObjectType.name, хранящийся в сохраненной строке NSString внутри ViewController.
Заранее спасибо!
1 ответ
Строка формата предиката будет выглядеть так:
@"ALL type.name=%@", typeName
Однако, поскольку у вас есть определенный объект MyObjectType, у вас уже есть прямой доступ к нужным объектам MyObject, и вам не нужно тратить время на их выборку. Просто конвертируйте набор в отсортированный массив.
Чтобы быть в курсе текущих изменений, пока таблица активна, внедрите observeValueForKeyPath:ofObject:change:context:
в объекте источника данных tableview. Затем отправьте addObserver:forKeyPath:options:context:
для этого конкретного объекта MyObjectType, например, так:
[anObjectType addObserver:self
forKeyPath:@"objects"
options:(NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld)
context:nil];
Теперь, когда objects
значение этого специфического MyObjectType изменится, источник данных tableview будет уведомлен и может изменить таблицу.
См. Руководство по программированию наблюдения значения ключа для деталей.