Извлечение управляемых объектов Core Data в среде Cocoa, Mac OS, iOS

Cocoa

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

Извлечение управляемых объектов

Вы производите выборку управляемых объектов путем отправки запроса выборки на управляемый объект контекста. Для начала вы создаете запрос для выборки. Как минимум вы должны указать объект для запроса. Вы можете получить сущности из управляемой модели объекта с помощью метода entityForName:inManagedObjectContext: NSEntityDescription. Также можно установить предикат, дескрипторы сортировки, и другие атрибуты при необходимости. Вы извлекаете объекты из контекста с использованием executeFetchRequest:error:, как показано в примере ниже.

Листинг 1 Пример создания и выполнения запроса выборки

NSManagedObjectContext *moc = [self managedObjectContext];

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

// Установить предикат примера и сортировку...

NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
   @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];
[request setPredicate:predicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];

[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
    // Обработка ошибки...
}

Вы не можете извлекать с использованием предикатов на основе переходных свойств (хотя вы можете использовать переходные свойства для фильтрации в памяти сами). Кроме того, есть некоторые взаимодействия между выборкой и типом хранилища. Чтобы подвести итог, если вы выполните выборки напрямую, вы не должны добавлять Objective-C предикаты или дескрипторы сортировки в запросы выборки. Вместо этого вы должны применить это к результатам выборки. Если вы используете контроллер массива, вам может понадобиться создать подкласс NSArrayController так что вы можете не производить сортировку в постоянном хранилище, а вместо этого сделать сортировку после того, как данные были извлечены.

Получение отдельных объектов

Если ваше приложение использует несколько контекстов, и вы хотите проверить, является ли объект удаленным из постоянного хранилища, вы можете создать запрос выборки с предикатом виде self ==%@. Объект, который вы передаете в качестве переменной может быть как управляемым объектом или ID управляемого объекта, как показано в следующем примере:

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];

NSEntityDescription *entity =
    [NSEntityDescription entityForName:@"Employee"
    inManagedObjectContext:managedObjectContext];

[request setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self == %@", targetObject];

[request setPredicate:predicate];

NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
    NSUInteger count = [array count]; // Может быть 0 если объект был удален.

    //

}
else {

    //Обработка ошибки...

}

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

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@", arrayOfManagedObjectIDs];

Получение определенных значений

Иногда вы не хотите получать фактические управляемые объекты, вместо этого вы просто хотите получить, например, наибольшее или наименьшее значения конкретного атрибута. В Mac OS X 10.6 и выше и в iOS, вы можете использовать NSExpressionDescription для непосредственного извлечения значений, которые отвечают вашим критериям.

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

  • Вы указываете, что выборка должна возвращать словари.

    Вы отправляете запросу выборки сообщение setResultType: с аргументом NSDictionaryResultType.

  • Вы создаете экземпляры NSExpressionDescription, чтобы указать свойства, которые вы хотите получить.

    Если вы просто хотите единственное значение, такое как крупнейшая зарплата в таблице Employee-то вы просто создаете единственное описание выражения.

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

  1. Прежде всего, необходимо создать выражения (экземпляры NSExpression) представляет ключ-путь к значению, которое вас интересует, и представить функцию, которую вы хотите применить (например, max: или min:):
    NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"salary"];
    NSExpression *maxSalaryExpression = [NSExpression expressionForFunction:@"max:"
          arguments:[NSArray arrayWithObject:keyPathExpression]];

    Полный список поддерживаемых функций expressionForFunction:arguments:

    ФункцияПараметрВозвращаетДоступно
    average:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (среднее значение в массиве)Mac OS X v10.4 и выше
    sum:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (сумма значений в массиве)Mac OS X v10.4 и выше
    count:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (количество элементов в массиве)Mac OS X v10.4 и выше
    min:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (минимальное значение в массиве)Mac OS X v10.4 и выше
    max:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (максимальное значение в массиве)Mac OS X v10.4 и выше
    median:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (среднее значение в массиве)Mac OS X v10.5 и выше
    mode:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (вид значений в массиве)Mac OS X v10.5 и выше
    stddev:NSArray объект, содержащий NSExpression объекты, представляющие числаОбъект NSNumber (стандартное расхождение значений в массиве)Mac OS X v10.5 и выше
    add:to:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (сумма значений в массиве)Mac OS X v10.5 и выше
    from:subtract:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (результат вычитания второго значения в массиве из первого значения в массиве)Mac OS X v10.5 и выше
    multiply:by:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (результат умножения значений в массиве)Mac OS X v10.5 и выше
    divide:by:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (результат деления первого значения в массиве на второе значение в массиве)Mac OS X v10.5 и выше
    modulus:by:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (остаток от деления первого значения в массиве на второе значение в массиве)Mac OS X v10.5 и выше
    sqrt:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (квадратный корень из значения в массиве)Mac OS X v10.5 и выше
    log:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (логарифм из значения в массиве)Mac OS X v10.5 и выше
    ln:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (натуральный логарифм из значения в массиве)Mac OS X v10.5 и выше
    raise:toPower:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (результат возведения первого значения в массиве в степень второго значения в массиве)Mac OS X v10.5 и выше
    exp:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (базированное на экспоненте значение в массиве)Mac OS X v10.5 и выше
    ceiling:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (наименьшее целое число, не меньше, чем значение в массиве)Mac OS X v10.5 и выше
    abs:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (абсолютная величина значения в массиве)Mac OS X v10.5 и выше
    trunc:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (значение интеграла ближайшего к, но не больше, чем значение в массиве)Mac OS X v10.5 и выше
    randomnilОбъект NSNumber (случайное целое значение)Mac OS X v10.5 и выше
    random:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (случайное число в диапазоне от 0 до значения в массиве (exclusive))Mac OS X v10.5 и выше
    nownilОбъект NSDate (текущее время и дата)Mac OS X v10.5 и выше
    floor:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumberiOS 3.0 и выше
    uppercase:NSArray объект, содержащий один NSExpression объект, представляющий строкуОбъект NSStringiOS 3.0 и выше
    lowercase:NSArray объект, содержащий один NSExpression объект, представляющий строкуОбъект NSStringiOS 3.0 и выше
    bitwiseAnd:with:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    bitwiseOr:with:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    bitwiseXor:with:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    leftshift:by:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    rightshift:by:NSArray объект, содержащий два NSExpression объекта, представляющих числаОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    onesComplement:NSArray объект, содержащий один NSExpression объект, представляющий числоОбъект NSNumber (число рассматривается как NSInteger)iOS 3.0 и выше
    noindex:NSArray объект, содержащий NSExpression объектВ результате оценки параметров, как будто noindex: функциональное выражение не существует.iOS 3.0 и выше
  2. Затем создать описание выражения и установить его имя, выражение и тип результата.

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

    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
    [expressionDescription setName:@"maxSalary"];
    [expressionDescription setExpression:maxSalaryExpression];
    [expressionDescription setExpressionResultType:NSDecimalAttributeType];
  3. И, наконец, установить свойства запроса на выборку только свойство представлено выражением:
    [request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

Затем можно выполнить выборку запроса так же, как любой другой (с помощью executeFetchRequest:error:). Запрос возвращается, хотя массив, содержащий словарь, ключей и значений соответствуют именам выражений описаний и значений, которые вы запросили.

В следующем примере показано, как можно получить минимальное значение атрибута "creationDate" в сущности с названием "Event".

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
[request setEntity:entity];

// Укажите, что запрос должен возвращать словари.

[request setResultType:NSDictionaryResultType];

// Создать выражение для пар ключ путь.

NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"creationDate"];

// Создание выражения представляющего минимальное значение для ключ пути 'creationDate'

NSExpression *minExpression = [NSExpression 
    expressionForFunction:@"min:" arguments:[NSArray arrayWithObject:keyPathExpression]];

// Создание выражения описания используя minExpression и возвращения даты.

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];

// name это ключ, который будет использоваться в словаре для возвращаемого значения.

[expressionDescription setName:@"minDate"];
[expressionDescription setExpression:minExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];

// Установка свойств запроса на выборку только свойства представленного выражением.

[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

 

// Выполнение запроса.

NSError *error = nil;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if (objects == nil) {

    // Обработка ошибки.

}
else {
    if ([objects count] > 0) {
        NSLog(@"Минимальная дата: %@", [[objects objectAtIndex:0] valueForKey:@"minDate"]);
    }
}
[expressionDescription release];
[request release];

Выборка и наследование сущности

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

 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac