Постановка задачи
Требуется удалить управляемый объект (строку таблицы) из контекста управляемых объектов (вашей базы данных).
Решение
Воспользуйтесь методом экземпляра deleteObject:, относящимся к классу NSManagedObjectContext:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self createNewPersonWithFirstName:@"Anthony"
lastName:@"Robbins"
age:51];
[self createNewPersonWithFirstName:@"Richard"
lastName:@"Branson"
age:61];
/* Сначала создаем запрос выборки данных. */
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSError *requestError = nil;
/* Теперь применим запрос выборки данных к контексту. */
NSArray *persons =
[self.managedObjectContext executeFetchRequest: fetchRequest
error:&requestError];
/* Убеждаемся, что получили массив. */
if ([persons count] > 0){
/* Удаляем последний контакт из массива. */
Person *lastPerson = [persons lastObject];
[self.managedObjectContext deleteObject: lastPerson];
NSError *savingError = nil;
if ([self.managedObjectContext save:&savingError]){
NSLog(@"Successfully deleted the last person in the array.");
} else {
NSLog(@"Failed to delete the last person in the array.");
}
} else {
NSLog(@"Could not find any Person entities in the context.");
}
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
В приведенном примере кода используется метод createNewPersonWithFirstName: lastName: age:, который мы написали в разделе 16.4.
Обсуждение
Можно удалять управляемые объекты (записи из таблицы базы данных) с помощью метода экземпляра deleteObject:, относящегося к классу NSManagedObjectContext.
Ни в одном из своих параметров этот метод не сообщает вам об ошибке, равно как и не возвращает значения BOOL. Таким образом, у вас нет надежного способа узнать, был ли объект успешно удален с помощью контекста управляемых объектов. Для получения этой информации лучше использовать метод isDeleted управляемого объекта.
С учетом данной информации изменим код, написанный ранее в этом разделе:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self createNewPersonWithFirstName:@"Anthony"
lastName:@"Robbins"
age:51];
[self createNewPersonWithFirstName:@"Richard"
lastName:@"Branson"
age:61];
/* Сначала создаем запрос выборки данных. */
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSError *requestError = nil;
/* Теперь применим запрос выборки данных к контексту. */
NSArray *persons =
[self.managedObjectContext executeFetchRequest: fetchRequest
error:&requestError];
/* Убеждаемся, что получили массив. */
if ([persons count] > 0){
/* Удаляем последний контакт из массива. */
Person *lastPerson = [persons lastObject];
[self.managedObjectContext deleteObject: lastPerson];
if ([lastPerson isDeleted]){
NSLog(@"Successfully deleted the last person…");
NSError *savingError = nil;
if ([self.managedObjectContext save:&savingError]){
NSLog(@"Successfully saved the context.");
} else {
NSLog(@"Failed to save the context.");
}
} else {
NSLog(@"Failed to delete the last person.");
}
} else {
NSLog(@"Could not find any Person entities in the context.");
}
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
После запуска приложения в окне консоли отобразится примерно следующий результат:
Successfully deleted the last person… // последний контакт успешно удален
Successfully saved the context. // контекст успешно сохранен
16.6. Сортировка данных в Core Data
Постановка задачи
Требуется сортировать управляемые объекты (записи), выбираемые из контекста управляемых объектов (базы данных).
Решение
Нужно создать по экземпляру класса NSSortDescriptor для каждого атрибута (в терминологии баз данных — столбца) той сущности, в которой требуется произвести сортировку. Дескрипторы сортировки добавляются к массиву, а сам массив присваивается экземпляру NSFetchRequest с помощью метода экземпляра setSortDescriptors:. В данном коде, приведенном в качестве примера, Sorting_Data_in_Core_DataAppDelegate — это класс, представляющий делегат универсального приложения (о том, как создается сущность Person, рассказано в разделах 16.1 и 16.2:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self createNewPersonWithFirstName:@"Richard"
lastName:@"Branson"
age:61];
[self createNewPersonWithFirstName:@"Anthony"
lastName:@"Robbins"
age:51];
/* Сначала создаем запрос выборки данных. */
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:@"Person"];
NSSortDescriptor *ageSort =
[[NSSortDescriptor alloc] initWithKey:@"age"
ascending: YES];
NSSortDescriptor *firstNameSort =
[[NSSortDescriptor alloc] initWithKey:@"firstName"
ascending: YES];
fetchRequest.sortDescriptors = sortDescriptors;
/* Сообщаем запросу, что сначала мы хотим
считать содержимое сущности Person. */
[fetchRequest setEntity: entity];
NSError *requestError = nil;
/* Теперь применим запрос выборки данных к контексту. */
NSArray *persons =
[self.managedObjectContext executeFetchRequest: fetchRequest
error:&requestError];
for (Person *person in persons){
NSLog(@"First Name = %@", person.firstName);
NSLog(@"Last Name = %@", person.lastName);
NSLog(@"Age = %lu", (unsigned long)[person.age unsignedIntegerValue]);
}
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Обсуждение
Экземпляр класса NSFetchRequest может нести с собой массив экземпляров NSSortDescriptor. Каждый дескриптор сортировки определяет атрибут (столбец) актуальной сущности, в которой необходимо произвести сортировку. Кроме того, он указывает порядок сортировки — восходящий или нисходящий. Например, сущность Person, которую мы создали в разделе 16.1, имеет атрибуты firstName, lastName и age. Если мы хотим считать все контакты в контексте управляемых объектов и отсортировать этих людей по возрасту, от самого младшего до самого старшего, то создадим экземпляр NSSortDescriptor с ключом age и зададим для него восходящий порядок (ascending):
NSSortDescriptor *ageSortDescriptor =
[[NSSortDescriptor alloc] initWithKey:@"age"
ascending: YES];
Запросу выборки данных можно присвоить более одного дескриптора сортировки. Порядок расположения данных в массиве определяет и порядок, в котором задаются дескрипторы. Иными словами, вывод сортируется по первому дескриптору в массиве, в полученном множестве записи сортируются по второму дескриптору в массиве и т. д.
См. также
Раздел 16.4.
16.7. Оптимизация доступа к данным в табличных видах