Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

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

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

Оглавление:

Введение

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

Проектирование базы данных

Заокеанский философ Ралф Уолдо Эмерсон некогда сказал: «A foolish consistency is the hobgoblin of little minds» (Тупое следование чему-то, это доля балбесов). Люди частенько применяют это высказывание в целях охраны себя от нападок и вопросов со стороны других к деталям. Верим, что мы не попадёмся на эту удочку, правда мы периодично утверждаем, что Core Data не является базой данных, впрочем относимся к ней, как к базе данных (автор: что-то вспоминается «если что-то ходит как утка, крякает как утка, значит это утка»). В этой сегменты разглядим, каким образом проектировать конструкцию данных приложения, а проведение параллели этого процесс к процессу проектированию конструкции реляционной базы данных нам дюже поможет не только обсуждением, но собственно и финальным итогом. В некоторых точках безусловно аналогии не будет существовать, но в ходе дискуссии мы постараемся подметить эти точки.

Сущности в Core Data выглядят, действуют, пахнут и на вкус такие же, как таблицы в реляционных базах данных. Признаки — это поля таблицы, связи — JOINы по первичным и внешним ключам, а сами сущности представляют собой те самые записи в таблицах. Если наша модель данных «накладывается» на SQLite тип хранилища, то Core Data собственно реализует всё именно таким образом, тот, что мы описали выше и в главах №2 / №3. Впрочем не стоит забывать, что ваши данные могут храниться в памяти, либо, скажем, в каком-то файле (атомарном хранилище), и тут теснее нет никаких таблиц и полей, первичных ключей и внешних. Core Data абстрагирует конструкцию данных от типа используемого хранилища, добиваясь тем самым комфорта и универсальности при проектировании и взаимодействии с данными. Дозвольте Core Data охватить ваш рассудок, слейтесь в цельное целое с Core Data: либо вы ощутите всё мощь с применением Core Data, либо вы окажетесь у разбитого корыта применяя неоптимальные конструкции данных.

Новички, которые только начинают постигать Core Data, создавая свои первые модели данных, непрерывно негодуют, что у них нет вероятности создавать и отвечать за первичные ключи в своих сущностях, как они привыкли это делать при традиционном моделировании конструкции базы данных. В Core Data нет никаких автоикрементирующихся ключей потому, что они там не необходимы. Core Data берет на себя ответственность за создание неповторимого ключа для всякого добавляемого о признака в случае, если не было указано значение. Reg. Ex. Регулярное выражение для проверки (валидации) данных

Просмотр и редактирование связей

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

Связи владеют несколькими свойствами. Во-первых, у них есть имя и финальная сущность (сущность вкоторую входит связь). Финальная сущность описывает тип объекта на тот, что указывает связь. Для сущности Player, связь «team», как полагается, указывает на сущность Team. Архитекторы Core Data сурово-настрого советуют указывать у всякой связи её обратную связь (inverse relashionship) — связь, которая направлена в обратную сторону. Скажем, сущность Player имеет связь с Team, значит исходя из рекомендации, как мы и реализовали, Team так же должна иметь связь с Player. По факту, если вы позабудете либо не захотите устанавливать обратную связь, то компилятором будет сгенерировано предупреждение. Добавочные два свойства доступны для признаков: Transient и Optional. Transient связь не сохраняется в хранилище во время операции сохранения. Если бы team связь была типа Transient, то при сохранении и дальнейшем перезапуске приложения терялась бы информации о том, какой команде принадлежит игрок. Объект Player по бывшему бы сохранялся, но его связь с объектом Team нет. Transient связи могут быть пригодны тогда, когда у вас есть надобность установить значения во время выполнения, скажем, пароля либо чего-то такого, что получается из информации получаемой во время работы приложения. Если же связь Optional, то это легко обозначает, что дозволено установить её в значение nil. Скажем, у игрока может не быть команды.

Множественность связи определяет кол-во финальных объектов, к которым начальный объект может относиться: к-одному либо ко-многим. По умолчанию связь является к-одному, что обозначает, что начальный объект может относиться лишь к одному финальному. Это как раз случай в примере с team к сущности Player: у игрока может быть не больше одной команды. Впрочем команда может иметь уйма игроков, именно следственно связь player в сущности Team имеет связь ко-многим. Эти значения (со стороны ко-многим) представляются в виде множества (NSSet) объектов. Множественность связи может быть также определена путём метаморфозы минимальных и максимальных значений, которые представляют собой мощностьфинального множества сущностей в связи.

В заключение, Core Data использует правила удаления связей для того, Дабы знать, что делать с финальными объектами при удалении начального. Есть уйма вариантов удаления, которые Core Data поддерживает. Присутствуют такие виды удалений: No action, Nullify, Cascade, Deny. Сегмент «Правила настройки» в этой главе, как раз и обговаривает правила удаления и их значение.

Применение запросов в качестве свойств

До сих пор в книге мы упоминали об признаках и связях теснее несколько раз. Третее качество, которым может владеть сущность: запрос (выборка). Запросы в качестве свойств, сравнимы со связями в том, что могут ссылаться на другие объекты. Если качество сущности типа «Связь» ссылается напрямую на финальные объекты, то «Запросы» (тоже качество сущности) ссылаются на объекты выбранные указанным предикатом. Запросы в качестве свойств представляют собой своего рода «разумные» списки проигрывания в iTunes, в котором пользователь указывает музыкальную библиотеку, а после этого фильтрует содержимое по определенным критериям. Правда запросы в качестве свойств и не ведут себя настоль идентично с выборкой в iTunes, они вычисляются однажды при первом запросе, итоги этой выборки кэшируются до тех пор, пока мы сами не скажем, что нужно обновиться, вызвав способ refreshObject:mergeChanges:.

В League Manager приложении мы можем, скажем, сделать качество запрос, которое будет возвращать всех игроков из команды, чьи имена начинаются на «W». Выберите сущность Team, нажмите кнопку ” ” в разделе «Fetched Properties» и назовите новейший запрос wPlayers. Выберите сущность Player в качестве финальной (тип сущности, которая будет запрашиваться и возвращаться).

В поле «Predicate» укажите критерий для фильтра применяя типовой формат NSPredicate (подробнее о формате и NSPredicate побеседуем в 6 главе). В указанном примере предикат будет выглядеть дальнейшим образом: lastName BEGINSWITH "W".

Позже этого, сделанный нами именной запрос, станет таким же признаком объекта Player, как и признак имени. Применять его дозволено таким же образом, как и прочие признаки. Дозволено уговоритьь Player и в выпадающем списке под наименованием «Parent Entity» выберите «Person»:

Сейчас у сущности Player будет доступен признак dateOfBirth.

Создание признаков

Признаки описывают сущность. Признаки сущности описывают нынешнее состояние сущности и могут быть представлены разными типами данных. Выберите всякую сущность, в сегменты «Attributes» нажмите на ” ” (добавление нового признака, не позабудьте указать имя). Рисунок ниже показывает допустимые настройки признака:

Ранее в этой главе мы теснее говорили о разных свойствах признаков. Вне всякого сомнения самым значимым свойством признака является его тип. По умолчанию Core Data предоставляет несколько типов:

Множество перечисленных выше типов напрямую связаны с типами данных в Objective-C. Исключительным типом, тот, что выпадает из всеобщей картины является тип Transformable, тот, что предуготовлен для настраиваемых (создаваемых программистом) типов. Рекомендуется применять Transformable тип в тех случаях, когда ни один из существующих типов не может содержать требуемые вам данные. В качестве примера дозволено взять вновь таки наше приложение League Manager, в котором нужно беречь цвета, которые дозволено представить типом CGColorRef. В этом случае признак должен быть Transient и Transformable, а в тоже время мы обязаны будем представить Core Data механизм реформирования признака в теснее присутствующий тип. Используйте настраиваемые (кастомные) признаки в тех случаях, когда вы создаете свой класс, тот, что наследуется от NSManagedObject.

Создание связей

В процессе нормализации, вы скорее каждого будете создавать несколько сущностей, в зависимости от трудности модели данных. Связи разрешают связать сущности между собой, как это сделано в League Manager приложении с сущностями Player и Team. Core Data разрешает тюнинговать (раскаиваюсь, вот прям нравится это слово) связи, Дабы те в свою очередь, особенно верно отражали отношения между моделируемыми данными.

В Xcode при создании связи либо при выборе оной, мы видим комплект настроек, которые дозволят нам изменить природу связи. Скажем, если мы предпочтем связь team в сущности Player, что увидим приблизительно следующую картину:

Список полей:

  • Имя
  • Финальная сущность
  • Обратная связь
  • Переходный (Transient)
  • Опциональна
  • Является ли связь «ко-многим»
  • Кол-во (минимум и максимум)
  • Правила удаления

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

Название связи (Name)

Первое поле, Name, становится название признака NSManagedObject объекта относящегося к связи. По принятым соглашениям, название должно быть в нижнем регистре (lowercase). Если же связь является «ко-многим», то название должно принимать вид во мн. числе. Стоит понимать, что всё это лишь соглашения, следование которым дозволит сделать ваши модели больше внятными, читаемыми и легко поддерживаемыми. Дозволено подметить, что в приложении League Manager мы придерживаемся соглашений, следственно связь в сущности Player именуется team. В сущности же Team связь с игроками именуется «players».

Финальные и обратные сущности (Destination and Inverse)

Следующее поле, Destination, определяет сущность с иного конца связи. Inverse поле разрешает предпочесть ту же связь, но только со стороны финальной сущности.

Оставляя Inverse поле в значении No Inverse Relationship гарантирует вам приобретение 2-х предупреждение: оплошность согласованности и ненормально настроенный признак.

Вы можете не обращать внимания, в конце концов это каждого лишь предупреждения компилятора, а не ошибки, впрочем вы можете столкнуться с непредвиденными последствиями. Core Data использует двухстороннюю информацию о связи для поддержания согласованности объектного графа для обработки операции Redo/Undo. Оставляя связь без указания Inverse сущности, вы берете на себя ответственностьза поддержания согласованности объектного графа для выполнения операций Undo/Redo. Документация Apple сурово настрого не советует этого делать, в частности в случае применять связь «ко-многим». В случае, если вы не указываете обратную (Inverse) связь, то managed объект с иного конца связи не будет помечен, как измененный объект, если managed объект с этой стороны связи изменился.

Переходный (Transient)

Помечая связь, как «Transient» вы указываете Core Data, что эту связь не нужно сберегать в хранилище. Переходная связь всё еще поддерживает операции Redo/Undo, но пропадает при закрытии приложения. Вот несколько допустимых вариантов применения переходной связи:

  • Связи между сущностями, которые являются временными и не обязаны существовать дольше, чем нынешняя сессия запуска приложения
  • Информация о связи, которая может быть получена из каких-то внешних источников данных, будь-то другое Core Data хранилище либо какой-то иной источник информации

В большинстве случаев вы захотите, Дабы ваши связи были непрерывными и сохранялись.

Опциональный (Optional)

Следующее поле, Optional, является чекбоксом, тот, что определяет, может ли связь принимать значение nil либо нет. Считайте, что это что-то как бы NULL либо не-NULL значения в поле базы данных. Если чекбокс установлен, то сущность допустимо будет сберечь без указания связи. Если же попытаться сберечь сущность со сброшенным чекбоксом, то сохранение закончиться неудачей. Если в сущности Player в приложении League Manager оставить связь team со сброшенным чекбоксом, то всякий игрок должен будет принадлежать какой-то команде. Установка связи team в nil и последующем сохранении (вызове способа save:) приведет к ошибке с текстом «team is a required value».

Связь «ко-многим» (To-many)

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

число (минимальное и наивысшее)

Определяет кол-во объектов на той стороне связи, которые может иметь нынешний объект. Опция действует только в случае, если выбрана связь типа «ко-многим».
Превышение лимита при сохранении выдаст ошибку «Too many items», а неудовлетворительное кол-во — «Too few items».
Кстати, минимальное значение может быть огромнее максимального, что в целом устроит Core Data, так как проверки не производится. Следственно в случае, если минимальное значение будет огромнее максимального, любая попытка сберечь объектный граф провалится.

Правила удаления (Delete Rule)

Правила удаления определяют действия, которые нужно осуществить Core Data при удалении объекта со связями.
Существуют 4 типа удаления:
1. Cascade — начальный объект удаляется, все связанные (финальные) объекты удаляются тоже
2. Deny — если начальный объект связан с какими-то объектами, то удаления не происходит
3. Nullify — начальный объект удаляется, у всех связанных объектов обратная связь устанавливается в nil.
4. No Action — начальный объект удаляется, связанные объекты никак не меняются

В приложении League Manager, правило удаления для связи player является Cascade, что значит, что при удалении команды все её игроки будут так же удалены. Если бы мы изменили правило удаления на Deny, то удаления не случилось бы в случае, если у команды был бы правда бы один игрок. Установка же правила удаления в Nullify привела к тому, что все игроки остались бы в хранилище, но с обнуленной ссылкой на команду, в то время, как команда сама была бы удалена.

Качество перевода

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

Проголосовало 5 человек. Воздержалось 3 человека.

 

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB