Разработка iPhone/iPod touch приложений: CoreData. Что в имени твоем? (Часть 1) – Основные понятия
Объект – CoreData.
Задача – изучение параметров и возможностей.
Результат – получение общих понятий о возможностях и возможных применениях.
Итак. CoreData – что за зверь такой? Как говорит нам документация, это очень хороший и пушистый зверь, который всего лишь является надстройкой над конкретным хранилищем данных. а именно – над данными, которые хранятся в бинарном виде(CoreData-формат), XML, SQLite базе.
Что же все-таки позволяет сделать CoreData? Операции со сложными графами объектов, с множественными связями, валидацией, с возможностью осуществлять undo/redo операции на и… сохранять эти графы в некотором хранилище данных. Что получает от этого программист? Возможность не опускаться до уровня отщепенцев базы данных, не рассматривать проблему сериализации/десериализации, работая на уровне объектов.
Необходимо заметить, что CoreData справляется с этими задачами очень шустро, и не идет ни в какое сравнение по скорости и количеству кода с другими реализациями ORM под iPhone (будь то самописный ORM на основе SQLite, либо надстрока FMDB, либо SQLite Persistence Objects).
Кроме всего прочего, в SDK 3.0 появились специальные вспомогательные классы, позволяющие быстро интегрировать ввод/вывод данных, сохраненных с помощью CoreData. Так, при помощи NSFetchedResultsController можно без особых проблем использовать UITableView для отображения нескольких ТЫСЯЧ объектов.
Интересно? Читаем дальше …
Четыре слона CoreData
CoreData, как и многие другие объекты нашего плоского мира покоится на четырех слонах, которых обычно называют стеком CoreData (CoreData Stack). Разработчики из Apple дали им следующие имена:
- ManagedObjectContext
- ManagedObjectModel
- PersistentStoreCoordinator
- PersistentStore
Рассмотрим, за что отвечает каждый из них.
PersistentStore
Этот слон PersistenceStore отвечает за то, в каком виде хранятся объекты , и где они хранятся. CoreData умеет работать с четырьмя видами хранилищ – XML, SQLite, Binary и inMemory. Правда, XML-хранилище в iPhone SDK 3.0 отсутствует, так что, можно считать что с тремя. PersistenceStore не представлен никаким классом в iPhone SDK 3.0, соответственно не настраивается, и выбирается PersistenceStoreCoordinator’ом.
PersistentStoreCoordinator
PersistentStoreCoordinator дает возможность использовать одновременно несколько хранилищ объектов(PersistentStore). Мне, честно говоря, сложно сказать, в каком случае это может понадобиться, но факт остается фактом. Инициализируется он с помощью следующего вызова:
// Cоздаем SQLite Persistent Store
NSError *error;
NSURL * = [NSURL fileURLWithPath:[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"MyDataBaseName.sqlite"]];
NSPersistentStoreCoordinator * persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel: managedObjectModel];
if (![persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:nil error:&error]) {
// Handle error
}
В коде можно наблюдать переменную managedObjectModel, о которой сейчас и пойдет речь.
ManagedObjectModel
В библиотеке CoreData представлена Managed Object Model классом NSManagedObjectModel. Судя по названию эта слониха модель есть ни что иное как схема базы данных(если бы мы работали с БД, конечно). То есть хранит информацию о всех сущностях, о их связях, зависимостях, свойствах, запросах. Для упрощения создания такой модели, в Xcode присутствует специальный редактор(на картинке справа). Файлы моделей в проекте имеют расширение .xcdatamodel, и затем компилируются в .mom файлы, уже из которых можно инициализировать NSManagedObjectModel. В коде все выглядит намного проще:
// Инициируем модель из главного Bundle'а // mergedModelFromBundles - загрузит все .mom файлы, и попытается содать из них одну общую // модель. Обычно такой файл один, и проблем не возникает ;) // Бывают,конечно, исключения. Но сейчас речь не о них. NSManagedObjectModel * managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain]; // Создали и забыли. Обычно MOM используется всего один раз в программе - при добавлении // PersistenceStoreCoordinator'a
В результате выполнения кода создастся MOM, которая объединит все файлы моделей(один;), которые будут найдены в текущем bundle. А в редакторе MOM может выглядеть следующим образом:
После создания MOM, пора приниматься за создание объектов, которыми можно оперировать в приложении.
Managed Object
Managed Object – это объекты, которыми оперирует CoreData. Для удобства можно представить, что это те же самые NSObject – особой разницы не будет. Классы-Entity можно очень быстро сгенерировать из все того же редактора модели. Для этого надо открыть редактор модели, и, нажав Command-N выбрать “Managed Object Class”.
Выбираем классы, которые необходимы – и – готовые Классы-сущности уже в проекте. Все необходимые методы для работы со связями уже реализованы. Вот так, например, выглядит класс Body после генерации. Сразу обращаем внимание на методы доступа к связям, и на то что связи один ко многим представлены не в виде NSArray, а в виде NSSet.
#import <CoreData/CoreData.h>
@class Arm;
@class Head;
@class Leg;
@class Head;
@interface Body : NSManagedObject
{
}
@property (nonatomic, retain) NSSet* arms;
@property (nonatomic, retain) Head * head;
@property (nonatomic, retain) NSSet* legs;
@end
@interface Body (CoreDataGeneratedAccessors)
- (void)addArmsObject:(Arm *)value;
- (void)removeArmsObject:(Arm *)value;
- (void)addArms:(NSSet *)value;
- (void)removeArms:(NSSet *)value;
- (void)addLegsObject:(Leg *)value;
- (void)removeLegsObject:(Leg *)value;
- (void)addLegs:(NSSet *)value;
- (void)removeLegs:(NSSet *)value;
@end
С моделью, наконец-то, закончили. Остался еще один слон класс – NSManagedObjectContext
Managed Object Context
С этим слоном классом с одной стороны проще, с другой стороны – писать о нем нужно много, и подробно, так как с ним прийдется мучаться встречаться в процессе написания кода чаще всего (не считая NSFetchedRequest). Если проводить аналогии с БД, то Managed Object Context (MOC) – это транзакция. Если не принимать во внимание undoManager, то на этом сравнение можно и закончить. То есть, все объекты попадают в хранилище (БД) и из него, только через MOC. Контекстов можно создавать несколько, и каждый привязан к PersistenceStoreCoordinator’у, и знает куда сохранять и, соответственно, откуда загружать данные. Зачем могут понадобиться несколько MOC’ов? Как вариант – для независимого изменения и последующего сохранения классов-сущностей в хранилище.
Создается MOC очень просто:
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
Все. Ознакомление с основными понятиями CoreData можно считать законченым. Надеюсь, что прочитавшие статью теперь не будут больше бояться длинных названий вроде NSManagedObjectContext, NSManagedObjectModel, NSPersistenceCoordinator, и смогут представить за что они отвечают в CoreData. Про работу с NSManagedObjectContext, NSFetchedRequest и другими прелестями CoreData – я напишу отдельно.



















olgerd
в 23:37, 22.09.2009grand merci! ;)
…жду продолжения!
Makarov Alexey
в 9:04, 21.01.2010А что делать если нужны предопределенная заполненная default-значениями база. Как ее заполнять? Можете ссылку дать, где можно почитать об этом.
Kilew
в 11:51, 21.01.2010>А что делать если нужны предопределенная заполненная default-значениями база. Как ее заполнять? Можете ссылку дать, где можно почитать об этом.
В общем мы делали так:
1) Создаем АПП-1, забиваем базу нужными значениями, ложим ее в ресурсы АППа-2
2) АПП-2 (главный) первым делом проверяет, есть ли в папке Documents созданная база. Если нету, то копирует из ресурсов.
3) Апп-2 Всегда работает с базой из папки Documents.
Разработка iPhone/iPod touch приложений: CoreData. Что в имени твоем? (Часть 2) - Контексты и запросы < Stanfy Блог
в 20:27, 23.09.2009[...] в основных понятиях Core Data, можно начинать им пользоваться. Для простоты и [...]