NSFetchedResultsController
Оператор импорта
Swift
import CoreData
Objective C
@import CoreData;
Доступность
Доступный в iOS 3.0 и позже.
Вы используете выбранный контроллер результатов для эффективного управления, результаты возвратились из Базового запроса выборки Данных для предоставления данных для a UITableView объект.
В то время как табличные представления могут использоваться несколькими способами, выбранные контроллеры результатов прежде всего предназначаются для помощи Вам с основным представлением списка. UITableView ожидает, что его источник данных обеспечит ячейки как массив разделов, составленных из строк. Вы конфигурируете контроллер результатов выборки с помощью запроса выборки, указывающего объект, массив, содержащий по крайней мере одно упорядочивание вида, и дополнительно предикат фильтра. Выбранный контроллер результатов эффективно анализирует результат запроса выборки и вычисляет всю информацию о разделах в наборе результатов. Это также вычисляет всю информацию для индекса на основе набора результатов.
Кроме того, выбранные контроллеры результатов обеспечивают следующие функции:
Дополнительно наблюдайте изменения к объектам в связанном контексте управляемого объекта и изменениям отчета в наборе результатов его делегату (см. Делегата Контроллера).
Дополнительно кэшируйте результаты ее вычисления так, чтобы, если те же данные впоследствии восстановлены, работа не была повторена (см. Кэш).
Контроллер таким образом эффективно имеет три режима работы, определенные тем, имеет ли он делегата и определяется ли имя файла кэша.
Никакое отслеживание: делегат установлен в
nil.Контроллер просто обеспечивает доступ к данным, как это было, когда выполнялась выборка.
Отслеживание только для памяти: делегат не -
nilи имя кэша файла определяется кnil.Контроллер контролирует объекты в своем наборе результатов и разделе обновлений и информации для заказа в ответ на соответствующие изменения.
Полное персистентное отслеживание: делегат и имя кэша файла не -
nil.Контроллер контролирует объекты в своем наборе результатов и разделе обновлений и информации для заказа в ответ на соответствующие изменения. Контроллер поддерживает персистентный кэш результатов его вычисления.
Используя NSFetchedResultsController
Создание выбранного контроллера результатов
Вы обычно создаете экземпляр NSFetchedResultsController как переменная экземпляра контроллера табличного представления. При инициализации контроллера результатов выборки Вы обеспечиваете четыре параметра:
Запрос выборки. Это должно содержать по крайней мере один дескриптор вида для упорядочивания результатов.
Контекст управляемого объекта. Контроллер использует этот контекст для выполнения запроса выборки.
Дополнительно, ключевой путь на объектах результата, возвращающий имя раздела. Контроллер использует ключевой путь для разделения результатов на разделы (передача
nilуказывает, что контроллер должен генерировать единственный раздел).Дополнительно, имя файла кэша контроллер должно использовать (передача
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:fetchRequestmanagedObjectContext:contextsectionNameKeyPath:nilcacheName:@"<#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];} elsereturn 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];} elsereturn 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");}
Изменение запроса выборки
Вы не можете просто изменить запрос выборки для изменения результатов. Если Вы хотите изменить запрос выборки, Вы должны:
Если Вы используете кэш, удаляете его (использование
deleteCacheWithName:).Обычно Вы не должны использовать кэш при изменении запроса выборки.
Измените запрос выборки.
Вызвать
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: на всех известных разделах.
-
init (fetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:) - initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:Возвращается контроллер запроса выборки инициализировал использование данных параметров.
Объявление
Swift
init(fetchRequestfetchRequest: NSFetchRequest, managedObjectContextcontext: NSManagedObjectContext, sectionNameKeyPathsectionNameKeyPath: String?, cacheNamename: String?)Objective C
- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequestmanagedObjectContext:(NSManagedObjectContext *)contextsectionNameKeyPath:(NSString *)sectionNameKeyPathcacheName:(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) -> BoolObjective 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Имя файла кэша для удаления.
Если
namenil, удаляет все файлы кэша.Оператор импорта
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 и позже.
См. также
-
Возвращает объект в данном индексном пути в результатах выборки.
Объявление
Swift
func objectAtIndexPath(_indexPath: NSIndexPath) -> AnyObjectObjective 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 и позже.
-
Возвращает число раздела для данного заголовка раздела и индекса в индексе раздела.
Объявление
Параметры
titleЗаголовок раздела
sectionIndexИндекс раздела.
Возвращаемое значение
Число раздела для данного заголовка раздела и индекса в индексе раздела
Обсуждение
Вы обычно вызывали бы этот метод при выполнении
UITableViewDataSourcetableView:sectionForSectionIndexTitle:atIndex:метод.Оператор импорта
Objective C
@import CoreData;Swift
import CoreDataДоступность
Доступный в iOS 3.0 и позже.
-
Возвращает соответствующий элемент индекса раздела для данного имени раздела.
Объявление
Параметры
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 и позже.
