Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека Разработчика iOS

Разработчик

Ссылка платформы CoreData ссылка класса NSFetchedResultsController

Опции
Развертывание Target:

На этой странице
Язык:

NSFetchedResultsController

Наследование


Соответствует


Оператор импорта


Swift

import CoreData

Objective C

@import CoreData;

Доступность


Доступный в iOS 3.0 и позже.

Вы используете выбранный контроллер результатов для эффективного управления, результаты возвратились из Базового запроса выборки Данных для предоставления данных для a UITableView объект.

В то время как табличные представления могут использоваться несколькими способами, выбранные контроллеры результатов прежде всего предназначаются для помощи Вам с основным представлением списка. UITableView ожидает, что его источник данных обеспечит ячейки как массив разделов, составленных из строк. Вы конфигурируете контроллер результатов выборки с помощью запроса выборки, указывающего объект, массив, содержащий по крайней мере одно упорядочивание вида, и дополнительно предикат фильтра. Выбранный контроллер результатов эффективно анализирует результат запроса выборки и вычисляет всю информацию о разделах в наборе результатов. Это также вычисляет всю информацию для индекса на основе набора результатов.

Кроме того, выбранные контроллеры результатов обеспечивают следующие функции:

  • Дополнительно наблюдайте изменения к объектам в связанном контексте управляемого объекта и изменениям отчета в наборе результатов его делегату (см. Делегата Контроллера).

  • Дополнительно кэшируйте результаты ее вычисления так, чтобы, если те же данные впоследствии восстановлены, работа не была повторена (см. Кэш).

Контроллер таким образом эффективно имеет три режима работы, определенные тем, имеет ли он делегата и определяется ли имя файла кэша.

  1. Никакое отслеживание: делегат установлен в nil.

    Контроллер просто обеспечивает доступ к данным, как это было, когда выполнялась выборка.

  2. Отслеживание только для памяти: делегат не -nil и имя кэша файла определяется к nil.

    Контроллер контролирует объекты в своем наборе результатов и разделе обновлений и информации для заказа в ответ на соответствующие изменения.

  3. Полное персистентное отслеживание: делегат и имя кэша файла не -nil.

    Контроллер контролирует объекты в своем наборе результатов и разделе обновлений и информации для заказа в ответ на соответствующие изменения. Контроллер поддерживает персистентный кэш результатов его вычисления.

Используя NSFetchedResultsController

Создание выбранного контроллера результатов

Вы обычно создаете экземпляр NSFetchedResultsController как переменная экземпляра контроллера табличного представления. При инициализации контроллера результатов выборки Вы обеспечиваете четыре параметра:

  1. Запрос выборки. Это должно содержать по крайней мере один дескриптор вида для упорядочивания результатов.

  2. Контекст управляемого объекта. Контроллер использует этот контекст для выполнения запроса выборки.

  3. Дополнительно, ключевой путь на объектах результата, возвращающий имя раздела. Контроллер использует ключевой путь для разделения результатов на разделы (передача nil указывает, что контроллер должен генерировать единственный раздел).

  4. Дополнительно, имя файла кэша контроллер должно использовать (передача nil предотвращает кэширование). Используя кэш может избежать издержек вычислений раздела и индексировать информацию.

После создания экземпляра Вы вызываете performFetch: фактически выполнить выборку.

  • NSManagedObjectContext *context = <#Managed object context#>;
  • NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  • // Configure the request's entity, and optionally its predicate.
  • NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"<#Sort key#>" ascending:YES];
  • NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
  • [fetchRequest setSortDescriptors:sortDescriptors];
  • [sortDescriptors release];
  • [sortDescriptor release];
  • NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
  • initWithFetchRequest:fetchRequest
  • managedObjectContext:context
  • sectionNameKeyPath:nil
  • cacheName:@"<#Cache name#>"];
  • [fetchRequest release];
  • NSError *error;
  • BOOL success = [controller performFetch:&error];

Делегат контроллера

При установке делегата к выбранному контроллеру результатов контроллер регистрируется для получения уведомлений изменения из его контекста управляемого объекта. Любое изменение в контексте, влияющем на набор результатов или информацию о разделе, обрабатывается, и результаты обновляются соответственно. Контроллер уведомляет делегата, когда объекты результата изменяют местоположение или когда разделы изменяются (см. NSFetchedResultsControllerDelegate). Вы обычно используете эти методы для обновления дисплея табличного представления.

Кэш

Где возможно, контроллер использует кэш для предотвращения потребности повторить работу, выполняемую в установке любых разделов и упорядочивании содержания. Кэш сохраняется через запуски Вашего приложения.

Когда Вы инициализируете экземпляр NSFetchedResultsController, Вы обычно указываете имя кэша. (Если Вы не указываете имя кэша, контроллер не делает данных кэша.) При создании контроллера он ищет существующий кэш с именем:

  • Если контроллер не может найти надлежащий кэш, он вычисляет требуемые разделы и порядок объектов в разделах. Это тогда пишет эту информацию в диск.

  • Если это находит кэш с тем же именем, контроллер тестирует кэш, чтобы определить, допустимо ли его содержание все еще. Контроллер сравнивает текущее имя объекта, хеш версии объекта, дескрипторы вида и ключевой путь раздела с сохраненными в кэше, а также дате модификации кэшируемого информационного файла и персистентного файла хранилища.

    Если кэш является соответствующим текущей информации, контроллер снова использует ранее вычисленную информацию.

    Если кэш не является соответствующим текущей информации, то запрошенная информация повторно вычислена, и обновленный кэш.

Любое время раздел и изменение информации для заказа, кэш обновляется.

Если у Вас есть многократные выбранные контроллеры результатов с различными конфигурациями (различные дескрипторы вида и т.д.), необходимо дать каждому различное имя кэша.

Можно произвести чистку использования кэша deleteCacheWithName:.

Реализация методов источника данных табличного представления

Вы спрашиваете объект предоставить релевантную информацию в Вашей реализации методов источника данных табличного представления:

  • - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  • return [[<#Fetched results controller#> sections] count];
  • }
  • - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
  • if ([[<#Fetched results controller#> sections] count] > 0) {
  • id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
  • return [sectionInfo numberOfObjects];
  • } else
  • return 0;
  • }
  • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  • UITableViewCell *cell = <#Get the cell#>;
  • NSManagedObject *managedObject = [<#Fetched results controller#> objectAtIndexPath:indexPath];
  • // Configure the cell with data from the managed object.
  • return cell;
  • }
  • - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
  • if ([[<#Fetched results controller#> sections] count] > 0) {
  • id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
  • return [sectionInfo name];
  • } else
  • return nil;
  • }
  • - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
  • return [<#Fetched results controller#> sectionIndexTitles];
  • }
  • - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
  • return [<#Fetched results controller#> sectionForSectionIndexTitle:title atIndex:index];
  • }

Реакция на изменения

В целом, NSFetchedResultsController разработан для реакции на изменения на уровне модели, путем информирования его делегата, когда объекты результата изменяют местоположение или когда изменяются разделы.

Если Вы позволяете пользователю переупорядочивать строки таблицы, то Ваша реализация методов делегата должна принять во внимание, это — видит NSFetchedResultsControllerDelegate.

Изменения не отражаются, пока контекст управляемого объекта контроллера не получил a processPendingChanges сообщение. Поэтому при изменении значения атрибута управляемого объекта так, чтобы его расположение в выбранном наборе результатов контроллера результатов изменилось бы, его индекс, как сообщается контроллером не будет обычно изменяться до конца цикла текущего события (когда processPendingChanges вызывается). Например, следующий фрагмент кода зарегистрировал бы «то же»:

  • NSFetchedResultsController *frc = <#A fetched results controller#>;
  • NSManagedObject *managedObject = <#A managed object in frc's fetchedObjects array#>;
  • NSIndexPath *beforeIndexPath = [frc indexPathForObject:managedObject];
  • [managedObject setSortKeyAttribute:
  • <#A new value that changes managedObject's position in frc's fetchedObjects array#>;
  • NSIndexPath *afterIndexPath = [frc indexPathForObject:managedObject];
  • if ([beforeIndexPath compare:afterIndexPath] == NSOrderedSame) {
  • NSLog(@"same");
  • }

Изменение запроса выборки

Вы не можете просто изменить запрос выборки для изменения результатов. Если Вы хотите изменить запрос выборки, Вы должны:

  1. Если Вы используете кэш, удаляете его (использование deleteCacheWithName:).

    Обычно Вы не должны использовать кэш при изменении запроса выборки.

  2. Измените запрос выборки.

  3. Вызвать performFetch:.

Обработка объектного аннулирования

Когда контекст управляемого объекта уведомляет выбранный контроллер результатов, что отдельные объекты лишены законной силы, контроллер обрабатывает их как удаленные объекты и отправляет надлежащие вызовы делегата.

Для всех объектов в контексте управляемого объекта возможно быть лишенным законной силы одновременно. (Например, в результате вызова reset, или если хранилище удалено из персистентный координатор хранилища.), Когда это происходит, NSFetchedResultsController не лишает законной силы все объекты, и при этом это не отправляет отдельные уведомления за удалениями объекта. Вместо этого необходимо вызвать performFetch: для сброса состояния контроллера тогда перезагружают данные в табличном представлении (reloadData).

Проблемы Версии iOS

Существует несколько известных проблем и изменений поведения с NSFetchedResultsController на различных выпусках iOS.

iOS 4.0 и Позже

На iOS 4.0 и позже, NSFetchedResultsController если Вы снова используете тот же кэш для многократных контроллеров, тихо не исправляет результаты.

  • На iOS 4.0 и позже, NSFetchedResultsController не выполняет некоторые проверки, которые обнаружили бы, когда Вы ошибочно используете тот же кэш для многократных контроллеров. (Это происходит из оптимизации, которая может помочь избежать сложного сопоставления строк на запуске.) При многократном использовании того же кэша для многократных контроллеров Вы получите неправильные результаты.

 iOS 3.2 и Позже

На iOS 3.2 и позже, если кэш является устаревшим или nil, контроллер пытается вычислить информацию о разделе непосредственно в базе данных вместо того, чтобы выбрать объекты. Это не возможно если sectionNameKeyPath включает любые свойства, которые не являются персистентными. В этом случае контроллер выберет объекты вычислить разделы.

Предварительная iOS 4.0

До iOS 4.0 существует много известных проблем с делегатами, обрабатывающими обратные вызовы. Во многих случаях необходимо просто использовать

  • - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
  • [self.tableView reloadData];
  • }

вместо обновлений на строку. Для лучшего пользовательского опыта Вы призваны проверить число версии ОС и использовать более прекрасные гранулярные методы делегата только для устройств рабочий iOS 4.0 и позже.

NSFetchedResultsController не делает разделов поддержки, удаляемых в результате управляемого UI изменения.

Разделение на подклассы примечаний

Если Вы хотите настроить создание индексных заголовков и разделов, Вы создаете подкласс этого класса. Вы переопределяете sectionIndexTitleForSectionName: если Вы хотите, чтобы индексный заголовок раздела был чем-то другим, чем капитализированная первая буква имени раздела. Вы переопределяете sectionIndexTitles если Вы хотите, чтобы индексные заголовки были чем-то другим, чем массив, создаваемый путем вызова sectionIndexTitleForSectionName: на всех известных разделах.

  • Возвращается контроллер запроса выборки инициализировал использование данных параметров.

    Объявление

    Swift

    init(fetchRequest fetchRequest: NSFetchRequest, managedObjectContext context: NSManagedObjectContext, sectionNameKeyPath sectionNameKeyPath: String?, cacheName name: String?)

    Objective C

    - (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext:(NSManagedObjectContext *)context sectionNameKeyPath:(NSString *)sectionNameKeyPath cacheName:(NSString *)name

    Параметры

    fetchRequest

    Запрос выборки раньше получал объекты.

    Запрос выборки должен иметь по крайней мере один дескриптор вида. Если контроллер генерирует разделы, первый дескриптор вида в массиве используется для группировки объектов в разделы; его ключ должен или совпасть с sectionNameKeyPath или относительное упорядочивание с помощью его ключа должно соответствовать то использование sectionNameKeyPath.

    context

    Управляемый объект тот, против который fetchRequest выполняется.

    sectionNameKeyPath

    Ключевой путь на объектах результата, возвращающий имя раздела. Передача nil указать, что контроллер должен генерировать единственный раздел.

    Имя раздела используется, чтобы предварительно вычислить информацию о разделе.

    Если этот ключевой путь не является тем же как указанным первым дескриптором вида в fetchRequest, они должны генерировать те же относительные упорядочивания. Например, первый дескриптор вида в fetchRequest мог бы указать ключ для персистентного свойства; sectionNameKeyPath мог бы указать ключ для переходного свойства, полученного из персистентного свойства.

    name

    Имя файла кэша получатель должно использовать. Передача nil предотвратить кэширование.

    Предварительно вычисленная информация раздела кэшируется к частному каталогу под этим именем. Если Базовые Данные считают кэш сохраненным этим именем, они проверяются, чтобы видеть, соответствуют ли они fetchRequest. Если это делает, кэш загружается непосредственно — это избегает издержек вычислений информация об индексе и раздел. Если кэшируемая информация не соответствует запрос, кэш удален и повторно вычислен, когда происходит выборка.

    Возвращаемое значение

    Получатель, инициализированный с указанным запросом выборки, контекстом, ключевым путем и именем кэша.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • Выполняет запрос выборки получателя.

    Объявление

    Swift

    func performFetch(_ error: NSErrorPointer) -> Bool

    Objective C

    - (BOOL)performFetch:(NSError **)error

    Параметры

    error

    Если выборка не успешна, по возврату содержит ошибочный объект, описывающий проблему.

    Возвращаемое значение

    YEStrue если выборка выполнилась успешно, иначе NOfalse.

    Обсуждение

    После выполнения этого метода можно получить доступ к получателю выбранные объекты со свойством fetchedObjects.

    Специальные замечания

    Этот метод возвраты NOfalse (и подходящая ошибка в error) если запрос выборки не включает дескриптор вида, использующий ключевой путь имени раздела, указанный в initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • fetchRequest Свойство

    Запрос выборки раньше делал выборку.

    Объявление

    Swift

    var fetchRequest: NSFetchRequest { get }

    Objective C

    @property(nonatomic, readonly) NSFetchRequest *fetchRequest

    Специальные замечания

    Если Вы хотите изменить запрос выборки, необходимо выполнить шаги, описанные в Изменении Запроса Выборки.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • managedObjectContext Свойство

    Контекст управляемого объекта раньше выбирал объекты.

    Объявление

    Swift

    var managedObjectContext: NSManagedObjectContext { get }

    Objective C

    @property(nonatomic, readonly) NSManagedObjectContext *managedObjectContext

    Обсуждение

    Контроллер регистрируется, чтобы послушать уведомления изменения на этом контексте и должным образом обновить его набор результатов и информацию о разделе. 

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • sectionNameKeyPath Свойство

    Ключевой путь на выбранных объектах раньше определял раздел, которому они принадлежат.

    Объявление

    Swift

    var sectionNameKeyPath: String? { get }

    Objective C

    @property(nonatomic, readonly) NSString *sectionNameKeyPath

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • cacheName Свойство

    Имя файла раньше кэшировало информацию о разделе.

    Объявление

    Swift

    var cacheName: String? { get }

    Objective C

    @property(nonatomic, readonly) NSString *cacheName

    Обсуждение

    Сам файл хранится в частном каталоге; можно только получить доступ к нему по имени использование deleteCacheWithName:

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • delegate Свойство

    Объект, уведомляющийся, когда изменились выбранные результаты.

    Объявление

    Swift

    unowned(unsafe) var delegate: NSFetchedResultsControllerDelegate?

    Objective C

    @property(nonatomic, assign) id< NSFetchedResultsControllerDelegate > delegate

    Специальные замечания

    Если Вы не указываете делегата, контроллер не отслеживает изменения в управляемых объектах, связанных с его контекстом управляемого объекта.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • Удаляет кэшируемую информацию о разделе с именем.

    Объявление

    Swift

    class func deleteCacheWithName(_ name: String?)

    Objective C

    + (void)deleteCacheWithName:(NSString *)name

    Параметры

    name

    Имя файла кэша для удаления.

    Если name nil, удаляет все файлы кэша.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • fetchedObjects Свойство

    Результаты выборки.

    Объявление

    Swift

    var fetchedObjects: [AnyObject]? { get }

    Objective C

    @property(nonatomic, readonly) NSArray *fetchedObjects

    Обсуждение

    Значение свойства nil если performFetch: не был вызван.

    Массив результатов только включает экземпляры объекта, указанного запросом выборки (fetchRequest) и то соответствие его предикат. (Если запрос выборки не имеет никакого предиката, то массив результатов включает все экземпляры объекта, указанного запросом выборки.)

    Массив результатов отражает состояние в памяти управляемых объектов в контексте управляемого объекта контроллера, не их состояние в персистентном хранилище. Возвращенный массив, однако, не обновляет, поскольку управляемые объекты вставлены, изменены или удалены.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

    См. также

    executeFetchRequest:error:

  • Возвращает объект в данном индексном пути в результатах выборки.

    Объявление

    Swift

    func objectAtIndexPath(_ indexPath: NSIndexPath) -> AnyObject

    Objective C

    - (id)objectAtIndexPath:(NSIndexPath *)indexPath

    Параметры

    indexPath

    Индексный путь в результатах выборки.

    Если indexPath не описывает допустимый индексный путь в результатах выборки, исключение повышено.

    Возвращаемое значение

    Объект в данном индексе соединяет каналом в результатах выборки.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • Возвращает индексный путь данного объекта.

    Объявление

    Swift

    func indexPathForObject(_ object: AnyObject) -> NSIndexPath?

    Objective C

    - (NSIndexPath *)indexPathForObject:(id)object

    Параметры

    object

    Объект в результатах выборки получателя.

    Возвращаемое значение

    Индексный путь object в результатах выборки получателя, или nil если object не мог быть найден.

    Специальные замечания

    В версиях iOS прежде 3.2, этот метод повышает исключение если object не содержится в результатах выборки получателя.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • sections Свойство

    Разделы для результатов выборки получателя.

    Объявление

    Swift

    var sections: [AnyObject]? { get }

    Objective C

    @property(nonatomic, readonly) NSArray *sections

    Обсуждение

    Объекты в массиве разделов реализуют NSFetchedResultsSectionInfo протокол.

    Вы обычно используете массив разделов при реализации UITableViewDataSource методы, такой как numberOfSectionsInTableView: и tableView:titleForHeaderInSection:.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • Возвращает число раздела для данного заголовка раздела и индекса в индексе раздела.

    Объявление

    Swift

    func sectionForSectionIndexTitle(_ title: String, atIndex sectionIndex: Int) -> Int

    Objective C

    - (NSInteger)sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)sectionIndex

    Параметры

    title

    Заголовок раздела

    sectionIndex

    Индекс раздела.

    Возвращаемое значение

    Число раздела для данного заголовка раздела и индекса в индексе раздела

    Обсуждение

    Вы обычно вызывали бы этот метод при выполнении UITableViewDataSource tableView:sectionForSectionIndexTitle:atIndex: метод.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • Возвращает соответствующий элемент индекса раздела для данного имени раздела.

    Объявление

    Swift

    func sectionIndexTitleForSectionName(_ sectionName: String?) -> String?

    Objective C

    - (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName

    Параметры

    sectionName

    Имя раздела.

    Возвращаемое значение

    Элемент индекса раздела, соответствующий разделу с именем sectionName.

    Обсуждение

    Реализация по умолчанию возвращает капитализированную первую букву имени раздела.

    Необходимо переопределить этот метод при необходимости в различном способе преобразовать от имени раздела до его имени в индексе раздела.

    Специальные замечания

    Вам только нужен этот метод при использовании индекса раздела.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.

  • sectionIndexTitles Свойство

    Массив раздела индексирует заголовки.

    Объявление

    Swift

    var sectionIndexTitles: [AnyObject] { get }

    Objective C

    @property(nonatomic, readonly) NSArray *sectionIndexTitles

    Обсуждение

    Реализация по умолчанию возвращает массив, создаваемый путем вызова sectionIndexTitleForSectionName: на всех известных разделах. Если Вы хотите возвратить различный массив для индекса раздела, необходимо переопределить этот метод.

    Специальные замечания

    Вам только нужен этот метод при использовании индекса раздела.

    Оператор импорта

    Objective C

    @import CoreData;

    Swift

    import CoreData

    Доступность

    Доступный в iOS 3.0 и позже.