Базовые данные FAQ

Этот документ предоставляет ответы к вопросам, которые часто спрашивают о Базовых Данных.

Куда Контекст Управляемого объекта Прибывает Из?

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

В приложении единственного окна, если Вы создаете свой проект с помощью типичного помощника проектного менеджера, делегат приложения (экземпляр класса AppDelegate) снова создает контекст и предоставляет Вам доступ к нему через managedObjectContext метод. В этом случае, однако, код для создания контекста (и остальная часть Базового Стека данных) является явным. Это записано для Вас автоматически как часть шаблона.

Обратите внимание на то, что Вы не должны использовать экземпляры подклассов NSController непосредственно для выполнения выборок (например, Вы не должны создавать экземпляр NSArrayController в частности выполнить выборку). Контроллеры для управления взаимодействием между Вашими объектами модели и Вашим интерфейсом пользователя. На уровне объекта модели необходимо просто использовать контекст управляемого объекта для выполнения выборок непосредственно.

Как я инициализирую хранилище с данными по умолчанию?

Здесь существует две проблемы: создание данных и обеспечение данных импортируются только один раз.

Существует несколько способов создать данные.

Существует также несколько способов гарантировать, что значения по умолчанию импортируются только один раз:

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

Как я использую свою существующую базу данных SQLite с Базовыми Данными?

Вы не делаете. Несмотря на то, что Базовая Информационная поддержка SQLite как один из его персистентных типов хранилища, формат базы данных является частным. Вы не можете создать базу данных SQLite с помощью собственного API SQLite и использовать ее непосредственно с Базовыми Данными (и при этом Вы не должны управлять существующими Базовыми Данными хранилище SQLite с помощью собственного API SQLite). Если у Вас есть существующая база данных SQLite, необходимо импортировать ее в Базовое Хранилище данных (см. Эффективно Импортирующие Данные).

Я имею к - многие отношение от Объекта к Объекту B. Как я выбираю экземпляры Объекта B связанный с приведенным примером Объекта A?

Вы не делаете. Более в частности нет никакой потребности явно выбрать целевые экземпляры, Вы просто вызываете надлежащее кодирование значения ключа или метод доступа для экземпляра Объекта A. Если отношение вызывают «виджетами», то, если Вы реализовали пользовательский класс со столь же именованным методом доступа, Вы просто пишете:

NSSet *asWidgets = [instanceA widgets];

Иначе Вы используете кодирование значения ключа:

NSMutableSet *asWidgets = [instanceA mutableSetValueForKey:@"widgets"];

Как я выбираю объекты в том же порядке, я создал их?

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

Как я копирую управляемый объект от одного контекста до другого?

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

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

NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *copy = [context2 objectWithID:objectID];

У меня есть ключ, значение которого зависит от значений атрибутов в связанном объекте — как я гарантирую, что оно усовершенствовано, поскольку значения атрибута являются изменениями и поскольку управляют отношением?

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

OS X v10.5 и позже для к - одно отношение

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

Например, Вы могли переопределить keyPathsForValuesAffectingValueForKey: как показано в следующем примере:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
 
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
 
    if ([key isEqualToString:@"fullNameAndDepartment"]) {
 
        NSSet *affectingKeys = [NSSet setWithObjects:@"lastName", @"firstName",
                                                     @"department.deptName", nil];
        keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys];
    }
    return keyPaths;
}

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

+ (NSSet *)keyPathsForValuesAffectingFullNameAndDepartment {
 
    return [NSSet setWithObjects:@"lastName", @"firstName",
                                 @"department.deptName", nil];
}

К - много отношений

keyPathsForValuesAffectingValueForKey: не позволяет ключевые пути, включающие в - многие отношение. Например, предположите, что у Вас есть объект Отдела с к - многие отношение (employees) Сотруднику и Сотруднику имеет a salary атрибут. Вы могли бы хотеть объект Отдела, имеют a totalSalary атрибут, зависящий от зарплат всех Сотрудников в отношении. Вы не можете сделать этого с, например, keyPathsForValuesAffectingTotalSalary и возврат employees.salary как ключ.

В обеих ситуациях существует два возможных решения:

  1. Можно использовать наблюдение значения ключа для регистрации родителя (в этом примере, Отделе) как наблюдатель соответствующего атрибута всех дочерних элементов (Сотрудники в этом примере). Необходимо добавить и удалить родителя как наблюдатель, поскольку дочерние объекты добавлены к и удалены из отношения (см. Регистрацию для Наблюдения Значения ключа). В observeValueForKeyPath:ofObject:change:context: метод Вы обновляете зависимое значение в ответ на изменения, как проиллюстрировано в следующем фрагменте кода:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
     
        if (context == totalSalaryContext) {
            [self updateTotalSalary];
        }
        else
        // Deal with other observations and/or invoke super...
    }
     
    - (void)updateTotalSalary {
     
        [self setTotalSalary:[self valueForKeyPath:@"employees.@sum.salary"]];
    }
     
    - (void)setTotalSalary:(NSNumber *)newTotalSalary
    {
        if (totalSalary != newTotalSalary) {
            [self willChangeValueForKey:@"totalSalary"];
            totalSalary = newTotalSalary;
            [self didChangeValueForKey:@"totalSalary"];
        }
    }
     
    - (NSNumber *)totalSalary {
     
        return totalSalary;
    }
  2. Можно зарегистрировать родителя в центре уведомления приложения как наблюдатель его контекста управляемого объекта. Родитель должен реагировать на соответствующие уведомления изменения, отправленные дочерними элементами способом, подобным этому для наблюдения значения ключа.

В разработчике предиката XCode, почему я не вижу свойств для выбранного предиката свойства?

Если Вы хотите создать предикат для выбранного свойства в разработчике предиката в XCode, но не видите свойств, Вы, вероятно, не установили целевой объект для выбранного свойства.

Насколько эффективный Базовые Данные?

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

Базовые Данные выглядят подобными EOF. Каковы различия?

Базовые Данные и EOF (Платформа Объектов Предприятия, поставляющая с WebObjects) совместно используют общее наследие, но имеют различные цели. EOF является основанной на Java платформой, соединяющейся как клиент с сервером базы данных. Базовые Данные являются платформой Объективной на базе С, разработанной для поддержки разработки настольного приложения. Базовая Информационная поддержка много функций, не поддерживавших EOF, и наоборот.

Функции, поддерживавшие только EOF

EOF позволяет Вам использовать пользовательский SQL, совместно использованные контексты редактирования и вложенные контексты редактирования. Базовые Данные не обеспечивают эквивалент EOModelGroupNSManagedObjectModel класс обеспечивает методы для слияния моделей от существующих моделей, и для получения объединенных моделей от пакетов.

Упреждающая выборка поддержек EOF и пакетный сбой отношений, в OS X v10.4 Базовые Данные не делают. В OS X v10.5 при создании запроса выборки можно использовать setRelationshipKeyPathsForPrefetching: указать ключ соединяет каналом для отношений, которые должны быть выбраны с целевым объектом.

Функции, поддерживавшие только базовыми данными

Базовая Информационная поддержка выбрала свойства; многократные конфигурации в модели управляемого объекта; локальные хранилища; агрегация хранилища (данные для данного объекта могут быть распространены через сети магазинов); настройка и локализация имен свойства и предупреждения проверки; и использование предикатов для проверки свойства.

Отображение класса

Существуют параллели между многими классами в Базовых Данных и EOF.

  • NSManagedObject соответствует EOGenericRecord.

  • NSManagedObjectContext соответствует EOEditingContext.

  • NSManagedObjectModel соответствует EOModel.

  • NSPersistentStoreCoordinator соответствует EOObjectStoreCoordinator.

  • NSEntityDescription, NSPropertyDescription, NSRelationshipDescription, и NSAttributeDescription соответствовать EOEntity, EOProperty, EORelationship, и EOAttribute соответственно.

Управление изменениями

Существует важное поведенческое различие между EOF и Базовыми Данными относительно распространения изменения. В Базовых Данных равноправные контексты управляемого объекта «не сохранены в синхронизации» таким же образом как редактирование контекстов в EOF. Учитывая два контекста управляемого объекта, подключенные к тому же персистентному координатору хранилища, и с «тем же» управляемым объектом в обоих контекстах, если Вы изменяете один из управляемых объектов тогда, сохраняют, другой не повторно дан сбой (изменения не распространены от одного контекста до другого). Если Вы изменяете, тогда сохраняют другой управляемый объект, то (по крайней мере, если Вы используете политику слияния по умолчанию) Вы получите оптимистический отказ блокировки.

Многопоточность

Политика для блокировки Базового контекста управляемого объекта Данных в многопоточной среде не является той же политикой что касается контекста редактирования в EOF.

Рабочий стол OS X

Эти вопросы только относятся к OS X/desktop.

Как я заставляю GUI проверять данные, вводимые пользователем?

Когда контекст управляемого объекта отправляется a, базовые Данные проверяют все управляемые объекты save: сообщение. Когда пользователь сохраняет документ, в Базовых Данных основанное на документе приложение это. У Вас может быть GUI, проверяют его, поскольку данные вводятся путем выбора опции «Validates Immediately» для привязки значения в Интерфейсном инспекторе привязки Разработчика. При установлении привязки программно Вы предоставляете в словаре параметров привязки значение YES (как NSNumber объект) для ключа NSValidatesImmediatelyBindingOption (см. параметры привязки).

Для получения дополнительной информации того, как записать пользовательские методы проверки, посмотрите примечания разделения на подклассы для NSManagedObject.

Когда я удаляю объекты из подробного табличного представления, которым управляет контроллер массива, почему они не удалены из графа объектов?

Если контроллер массива управляет набором объектов в месте назначения отношения, то по умолчанию удалить метод просто удаляет текущий выбор из отношения. Если Вы хотите, чтобы удаленные объекты были удалены из графа объектов, то необходимо включить опцию «Deletes Objects On Remove» для contentSet привязка.

Как я получаю отмену/восстановление бесплатно в моем не, архитектура документа базировала приложение?

В Базовых Данных основанное на документе приложение, стандарт NSDocument менеджер по отмене заменяется менеджером по отмене контекста управляемого объекта документа. В базируемом приложении не документа для настольного OS X делегат Вашего окна может предоставить менеджера по отмене контекста управляемого объекта, использующего windowWillReturnUndoManager: метод делегата. Если у Вашего делегата окна есть метод доступа для контекста управляемого объекта (как имеет место, если Вы используете шаблон Core Data Application), Ваша реализация windowWillReturnUndoManager: мог бы быть следующие.

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)sender {
    return [[self managedObjectContext] undoManager];
}