Использование постоянного хранилища Core Data в среде Cocoa, Mac OS, iOS

Cocoa

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

Создание и доступ к хранилищу

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

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

NSManagedObjectContext *moc = <#берем контекст#>;
NSPersistentStoreCoordinator *psc = [moc persistentStoreCoordinator];
NSError *error = nil;
NSDictionary *options =
    [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:1]
                    forKey:NSReadOnlyPersistentStoreOption];

NSPersistentStore *roStore =
    [psc addPersistentStoreWithType:NSXMLStoreType
                    configuration:nil URL:url
                    options:options error:&error];

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

NSPersistentStoreCoordinator *psc = <#Get a coordinator#>;
NSURL *myURL = <#URL к хранилищу#>>;
NSPersistentStore *myStore = [psc persistentStoreForURL:myURL];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setAffectedStores:[NSArray arrayWithObject:myStore]];

Изменение типа и размещения хранилища

Можно перенести хранилище из одного типа или места в другое (например, для операции Save As), используя метод NSPersistentStoreCoordinator migratePersistentStore:toURL:options:withType:error:. После вызова этого метода, оригинальное хранилище удаляется из координатора. Метод иллюстрируемый в следующем фрагменте кода, показывает, как можно перенести хранилище из одного места в другое. Если старый тип хранилища XML, то пример также преобразует его в SQLite

NSPersistentStoreCoordinator *psc = [aManagedObjectContext persistentStoreCoordinator];
NSURL *oldURL = <#URL к текущему хранилищу#>;
NSURL *newURL = <#URL к новомк хранилищу#>;
NSError *error = nil;
NSPersistentStore *xmlStore = [psc persistentStoreForURL:oldURL];
NSPersistentStore *sqLiteStore = [psc migratePersistentStore:xmlStore
    toURL:newURL
    options:nil
    withType:NSSQLiteStoreType
    error:&error];

Core Data следует ниже приведенной процедуре, чтобы осуществить мигрирацию хранилища:

  1. Создает временный стек
  2. Монтирует старое и новое хранилище
  3. Загружает все объекты из старого хранилища
  4. Переносит объекты в новое хранилище

    Объектам назначаются временные ID, затем присваиваются новому хранилищу. Затем, новое хранилище их сохраняет.

    Core Data затем информирует другие стеки, что идентификаторы объектов изменились (из старого в новое хранилище), что обеспечивает возможность продолжать работать после миграции.

  5. Размонтирует старое хранилище
  6. Возвращает новое хранилище

Ошибки возникают при:

  • Предоставлении недействительных параметров методу
  • Core Data не может добавить новое хранилище
  • Core Data не может удалить старое хранилище

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

Связь метаданных с хранилищем, для предоставления дополнительной информации и поддержки индексации Spotlight

Метаданные хранилища предоставляют дополнительную информацию о хранилище, которая непосредственно не связана ни с одной из сущностей в хранилище.

Метаданные представлены словарем. Core Data автоматически устанавливает пары ключ-значение, чтобы указать тип хранилища и его UUID. Вы можете добавить дополнительные ключи, которые могут быть полезны для вашего приложения, или один из стандартных функциональных ключей для поддержки индексации Spotlight (если вы также пишете подходящий импортер), такие как kMDItemKeywords.

Вы должны быть осторожны, с тем, какую информацию вы включили в метаданные. Во-первых, Spotlight накладывает ограничение на размер метаданных. Во-вторых, репликация всего документа в метаданных, вероятно, не реальна к использованию. Заметим, однако, что можно создать URL для идентификации конкретного объекта в хранилище (с использованием URIRepresentation)- URL может быть полезно включить в качестве метаданных.

Получение метаданных

Есть два способа получить метаданные для хранилища:

  1. Получив экземпляр постоянного хранилища, вы можете получить его метаданные с помощью метода экземпляра NSPersistentStoreCoordinator metadataForPersistentStore:.
  2. Можно извлекать метаданные из хранилища без накладных расходов на создание стека методом класса NSPersistentStoreCoordinator, metadataForPersistentStoreOfType:URL:error:.

Существует важное различие между этими подходами. Метод экземпляра, metadataForPersistentStore: возвращает метаданные, представленные на текущий момент в вашей программе, в том числе любые изменения, которые, возможно, были сделаны с момента запуска хранилища и последнего сохранения. Метод класса, metadataForPersistentStoreOfType:URL:error: возвращает метаданные, которые в настоящее время представлены ​​в самом хранилище. При наличии отложенных изменений в хранилище, возвращаемое значение может быть, следовательно, не синхронизировано.

Установка метаданных

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

  1. Получив экземпляр постоянного хранилища, вы можете установить его метаданные методом NSPersistentStoreCoordinator, setMetadata:forPersistentStore:.
  2. Вы можете установить метаданные без накладных расходов на создание стека методом класса NSPersistentStoreCoordinator, setMetadata:forPersistentStoreOfType:URL:error:

Существует снова важное различие между этими подходами. Если вы используете setMetadata:forPersistentStore: необходимо сохраниться в хранилище (через управляемый объект контекста), прежде чем новые метаданные будут сохранены. Если-же вы используете setMetadata:forPersistentStoreOfType:URL:error:, метаданные обновляются немедленно (и дата последнего изменения этого файла изменяется). Это различие имеет конкретные последствия, если вы используете NSPersistentDocument на OS X. При обновлении метаданных с помощью setMetadata:forPersistentStoreOfType:URL:error: в то время как вы активно работаете с постоянным хранилищем (то есть, в то время как файл был изменен), то при сохранении документа вы увидите предупреждение "Файл этого документа был изменен другим приложением, с момента Вашего открытия или сохранения". Чтобы избежать этого, вы должны вместо этого использовать setMetadata:forPersistentStore:. Чтобы найти постоянное хранилище документов, вы обычно запрашиваете координатор постоянного хранилища о своих постоянных хранилищах (persistentStores) и используете первый элемент в возвращаемом массиве.

Поскольку Core Data управляет значениями для NSStoreType и NSStoreUUID, вы должны сделать изменяемую (mutable) копию любых существующих метаданных перед установкой собственных ключей и значений, как показано в следующем фрагменте кода.

NSError *error;
NSURL *storeURL = <#URL к постоянному хранилищу#>;

NSDictionary *metadata =
    [NSPersistentStoreCoordinator metadataForPersistentStoreWithURL:storeURL error:&error]
if (metadata == nil) {
    /* Обрабатываем ошибку. */
}
else {
    NSMutableDictionary *newMetadata = [metadata mutableCopy];
    newMetadata[(NSString *)kMDItemKeywords] = @[ @"MyKeyWord"] ];
    // Устанавливаем дополнительные пары ключ-значение по мере необходимости.

    [NSPersistentStore setMetadata:newMetadata
                       forPersistentStoreWithURL:storeURL
                       error:&error];
}
 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac