Pro Core Data for iOS. Глава №2. Теоретическая часть

в 15:55, , рубрики: andrewshmig, core data, data store, iOS, mobile development, objective-c, разработка под iOS, метки: , , , ,

Читатели, добрый день!
Сегодня хочу начать вольный перевод книги Михаеля Привата и Роберта Варнера «Pro Core Data for iOS», которую можете скачать по этой ссылке. Каждая глава будет содержать теоретическую и временами практическую часть.

image

Содержание:

  • Глава №1. Приступаем (Практическая часть)
  • Глава №2. Усваиваем Core Data
  • Глава №3. Хранение данных: SQLite и другие варианты
  • Глава №4. Создание модели данных
  • Глава №5. Работаем с объектами данных
  • Глава №6. Обработка результатирующих множеств
  • Глава №7. Настройка производительности и используемой памяти
  • Глава №8. Управление версиями и миграции
  • Глава №9. Управление таблицами с использованием NSFetchedResultsController
  • Глава №10. Использование Core Data в продвинутых приложениях

Вступление

Многие разработчики, после первого знакомства с Core Data, считают его каким-то запутанным набором классов, который вместо того, чтобы упрощать работу с данными, наоборот, препятствует этому. Возможно это Rails разработчики, привыкшие к написанию динамических методов поиска и позволяющие принятым соглашениям выполнять за них всё грязную работу. Возможно это Java разработчик, который аннотирует Enterprise JavaBeans (EJB) и работает с Plain Old Java Objects (POJO). Кем бы ни были эти люди, чем бы они не занимались, они не воспринимают Core Data Framework таким какой он есть и его способы работы с данными, столько же разработчиков при виде того, как создаются «живые» интерфейсы с использованием Interface Builder кривятся и ухмыляются. Мы уверяем Вас, что Core Data это не очередная машина Рубена Голдберга. Классы в Core Data Framework скорее игроки Бостон Селтикс 1980 года и, когда вы поймете их подходы к игре, лишь тогда сможете оценить всё прелесть и законченность их игры и взаимодействия.

Знаете ли Вы?

Рубен Люциус Голдберг (англ. Reuben Lucius Goldberg; 1883—1970) — американский карикатурист, скульптор, писатель, инженер и изобретатель.
Голдберг более всего известен серией карикатур, в которых фигурирует так называемая «машина Руба Голдберга» — чрезвычайно сложное, громоздкое и запутанное устройство, выполняющее очень простые функции (например, огромная машина, занимающая целую комнату, цель которой — передвижение ложки с пищей от тарелки до рта человека).
В 1948 году Голдберг получил Пулитцеровскую премию за свои политические карикатуры, а в 1959 году — премию Banshees' Silver Lady Award.
Голдберг был одним из основателей и первым президентом Национального общества карикатуры. Его именем названа премия Рубена, которой организация награждает карикатурист года. В США ежегодно проходит конкурс машин Руба Голдберга.

image

В этой главе будут расписаны предназначения классов Core Data Framework, как по отдельности, так и при совместной их работе. Постарайтесь не спешить прочитать главу целиком. Исследуйте примеры, покопайтесь с ними, вводите код сами (никакого копипаста!) и запускайте на проверку.

Классы Core Data

В первой главе мы уже рассмотрели и создали самое простое приложение используя Core Data. Вы видели отрывки кода, какие классы были использованы, какие методы вызывались, в каком порядке этим самые методы вызывались и какие параметры этим методам передавались. Всё это для того делалось, чтобы понять каким образом работает Core Data. Вы слепо следовали тому, что вам говорили делать, возможно в некоторые моменты вы и недоумевали зачем это делается, но продолжали отстукивать на клавиатуре сладкие NSManagedObject, возможно вы задавали себе вопрос «А что будет, если сюда подставить другое значение?». Некоторые возможно даже попробовали заменить одно значение на другое, именно они получили что-то отличное от взрыва ;), а кто-то получил то, что и рассчитывал получить.

Эдвард Дейкстра, известный компьютерный исследователь и обладатель награды Тьюринга 1972 года за свою работу в области разработки языков программирования, говорил об элегантности, как о качестве, которое определяет победу или поражение, а не как о необязательной роскоши.

Знаете ли Вы?

Премия Тьюринга (англ. Turing Award) — самая престижная премия в информатике, вручаемая Ассоциацией вычислительной техники за выдающийся научно-технический вклад в этой области.

Премия учреждена Ассоциацией вычислительной техники в честь выдающегося английского учёного Алана Тьюринга, получившего первые глубокие результаты относительно вычислимости задолго до появления первых электронных вычислительных машин.
Премия ежегодно вручается одному или нескольким специалистам в области информатики и вычислительной техники, чей вклад в этой области оказал сильное и продолжительное влияние на компьютерное сообщество. Премия может быть присуждена одному человеку не более одного раза. В сфере информационных технологий премия Тьюринга имеет статус, аналогичный Нобелевской премии в академических науках. Впервые Премия Тьюринга была присуждена в 1966 году Алану Перлису за развитие технологии создания компиляторов.

В настоящее время премия спонсируется корпорациями Intel и Google и составляет 250 000 долларов США.

(с) Википедия

Core Data не только справляется с задачей хранения данных, но и делает это элегантно. Чтобы добиться этой элегантности у себя в кода, Вам необходимо понимать Core Data, а не гадать на кофейной гуще о том, как оно работает и вообще почему оно работает. После прочтения данной главы Вы в деталях поймете не только саму структуру Core Data Framework, но и то, каким образом фрэймворк решает сложные проблемы используя небольшой набором классов, делая решения простыми, понятными и элегантными. На протяжении главы мы будем строить и дополнять диаграмму классов Core Data Framework. От Вас не ускользнёт и тот факт, что не все классы будут принадлежать Core Data Framework, некоторые будут импортированы из Foundation Framework. Параллельно с теоретической частью мы будем разрабатывать маленькое приложение, которое будет работать с фиктивными организационными структурами (менеджеры, программисты, начальники, администраторы и тд).

Откройте XCode и создайте Single View Application:
image

Назовите проект OrgChart.
Подключите в проект Core Data (см. Глава №1). Запустите приложение и убедитесь, что оно не падает.
image

На изображении приведенном ниже отображены классы Core Data с которыми мы обычно работаем:
image

В нашем коде сохранение данных происходит путём добавления новых NSManagedObject в NSManagedObjectContext, а получение данных с помощью NSFetchRequest класса. Как было показано в Главе №1, среда управления объектами (managed object context) создается и инициализируется при помощи диспетчера хранилищ данных (persistent store coordinator), реализуемого классом NSPersistentStoreCoordinator, который в свою очередь определяется моделью данных, реализуемой классом NSManagedObjectModel. Оставшаяся часть главы будет посвящена рассмотрению того, каким образом создаются эти классы, как они взаимодействуют между собой и, как их использовать.

Использующиеся при создании модели данных классы

Как было ранее упомянуто в Главе №1, все приложения использующие Core Data должны иметь объектную модель хранимых данных. Модель определяет сущности и их свойства. У сущности есть три типа свойств:

  • Атрибуты
  • Отношения
  • Свойства выборки

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

Наименование класса Роль
NSManagedObjectModel Модель данных
NSEntityDescription Сущность в модели данных
NSPropertyDescription Абстрактное описание свойства сущности
NSAttributeDescription Атрибут сущности
NSRelationshipDescription Ссылка одной сущности на другую
NSFetchedPropertyDescription Описание подмножества экземпляров сущностей выбранным по определенному критерию

Таблица ниже показывает отношения между классами использующимися при определении модели. NSManagedObjectContext не ссылается, либо ссылается на несколько объектов сущностей NSEntityDescription. Каждая объектная сущность NSEntityDescription не ссылается, либо ссылается на несколько объектов NSPropertyDescription. NSPropertyDescription является абстрактным классом с тремя конкретными реализациями:

  • NSAttributeDescription
  • NSRelationshipDescription
  • NSFetchedPropertyDescription

image

Этого маленького кол-ва классов будет достаточно для того, чтобы описать любую модель данных, которая будет вами разрабатываться с использованием Core Data Framework. Как описывалось ранее в Главе №1, для создания модели необходимо открыть XCode, выбрать пункт меню File -> New -> New File и указать «Data Model». В этой секции мы создадим модель, которая будет представлять собой организационную структуру компании.
Создайте новую модель в XCode и назовите её OrgChart. В этой модели данных у организации есть директор (CEO). Для простоты представим, что у человека есть два атрибута: уникальный идентификатор служащего и имя. Теперь мы готовы приступить к определению модели данных.
Откройте модель данных и создайте новую сущность Organization. Как и человек, организация определяется своим уникальным идентификатором и именем. Добавьте два атрибута сущности Organization. Атрибуты представляют собой постоянные свойства сущности, которые могут содержать значения некоторого типа. Типы данных атрибутов описываются в классе NSAttributeType и каждый тип данных налагает некоторые ограничения на сущность. Например, если вы попробуете записать строку в свойство с целочисленным типом данных, то возникнет ошибка.
Таблица ниже описывает существующие типы:

Тип атрибута в XCode Тип атрибута в Objective-C Objective-C Описание
Integer 16 NSInteger16AttributeType NSNumber 16-битное целое
Integer 32 NSInteger32AttributeType NSNumber 32-битное целое
Integer 64 NSInteger64AttributeType NSNumber 64-битное целое
Decimal NSDecimalAttributeType NSDecimalNumber Целочисленное значение по основанию 10
Double NSDoubleAttributeType NSNumber Объектная обёртка типа double
Float NSFloatAttributeType NSNumber Объектная обёртка типа float
String NSStringAttributeType NSString Строка символов
Boolean NSBooleanAttributeType BOOL Объектная обёртка логического типа
Date NSDateAttributeType NSDate Дата и время
Binary data NSBinaryDataAttributeType NSData Двоичные данные
Transformable NSTransformableAttributeType Любой нестандартный тип Любой тип, который может быть переведён в стандартный

Примечание

В Главе №5 мы разберем тип Transformable подробнее. Transformable-аттрибуты это способ уведомить Core Data о том, что будут использовать нестандартные типы данных и, в процессе сохранения данных в локальное хранилище, мы сообщим, каким образом преобразовать этот тип к одному из уже существующих встроенных.

Назовём первый атрибут id, а второй name. По умолчанию при создании нового атрибута его тип автоматически устанавливается в Undefined и не позволят проекту быть скомпилированным. Ваша задача выбрать подходящий тип для каждого из создаваемых вами атрибутов сущности. Идентификаторы организации всегда будут целочисленного типа, поэтому выберем Integer 16 в качестве типа для id атрибута. Тип String используем для атрибута name.
На данном этапе ваш проект должен выглядеть следующим образом:
image

Если бы на данном этапе программа была бы запущена, то объектный граф выглядел бы следующим образом:
image

На графе видно, что модель данных NSManagedObjectModel ссылается на объект сущности NSEntityDescription, который называется Organization и использует тип NSManagedObject для свойства managedObjectClassName. У сущности есть два атрибута. Каждый атрибут содержит два свойства: имя и тип. В первом атрибуте имя id и тип NSInteger16AttributeType для свойств name и attributeType соответственно.

Таким же образом создайте вторую сущность с именем Person и двумя атрибутами: id и name. Теперь мы можем создать связь между сущностями Organization и Person и назвать её leader. Создать связь достаточно просто: нажимаем на кнопку "+" в разделе «Relationships», выбираем «Destination» и «Source». Теперь добавим еще одну связь между Person и Person и назовём её employees. Последняя созданная нами связь — это связь типа «один к одному», в то время, как у служащего могут быть несколько подчиненных, а значит и тип связи необходим «один ко многим».
Откройте панель справа в XCode, как это показано на рисунке:
image

И поставьте галочку напротив пункта «Plural: To-Many Relationship»:
image

Модель данных выглядит следующим образом:
image

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

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"OrgChart" withExtension:@"momd"];

_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Знание того, каким образом представлены объекты модели в Core Data, в основном не очень полезное, разве что вы занимаетесь написанием собственного хранилища данных или заинтересованы в генерировании модели данных программно на этапе выполнения. Аналогию можно провести с созданием программно UIView, вместо того, чтобы использовать готовые элементы предоставляемые Interface Builder'ом. Однако глубокое понимание того, каким образом работает Core Data, позволит вам предсказывать и избегать сложностей, проблем, и приведёт к решению трудностей креативным и элегентным способом.

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

Продолжение следует...

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

Автор: AndrewShmig

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js