Core Data — это фреймворк управления данными от Apple, предоставляющий объектно-реляционное отображение для iOS, macOS, tvOS и watchOS. Он автоматизирует сохранение, извлечение и фильтрацию объектов в приложении, работая поверх SQLite, XML или бинарного хранилища. По данным Apple Core Data Documentation, фреймворк использует концепции Managed Object Context и NSPersistentContainer для управления стеком персистентности.
Главное
Core Data — это фреймворк управления объектным графом и персистентностью, входящий в состав Cocoa Touch. Вопреки распространённому заблуждению, Core Data — не база данных, а слой управления объектами, который может использовать SQLite как одно из хранилищ. Основная задача Core Data — отслеживать изменения объектов, управлять их жизненным циклом и синхронизировать состояние с диском.
Фреймворк предоставляет граф объектов, где каждый Managed Object отслеживается контекстом на предмет изменений. При сохранении контекста все изменённые, добавленные и удалённые объекты фиксируются в постоянном хранилище одной транзакцией. Это избавляет разработчика от написания SQL-запросов и управления транзакциями вручную.
По данным статистики Swift Developer Survey (2025), Core Data используется в 52% iOS-приложений, работающих с локальными данными. Несмотря на появление современных альтернатив (SwiftData, Realm), Core Data остаётся основным фреймворком в существующих проектах Apple благодаря зрелости и глубокой интеграции с системой.
Используйте Core Data для проектов с моделью данных средней сложности, где нужны связи между объектами, откат изменений и автоматическое кэширование через faulting-механизм.
Архитектура Core Data построена вокруг концепции Managed Object Context — рабочей области, которая отслеживает все изменения объектов. Контекст поддерживает откат (undo/redo) через встроенный NSUndoManager, что позволяет реализовать черновики и отмену действий без ручного сохранения снапшотов состояния. При вызове save() контекст фиксирует все изменения одной транзакцией в постоянном хранилище, гарантируя атомарность и консистентность данных.
Модель данных Core Data определяется в файле .xcdatamodeld — визуальном редакторе Xcode, где описываются все Entity, их атрибуты и связи. При компиляции модель сериализуется в .momd и загружается через NSManagedObjectModel.
Entity — это описание типа данных, аналогичное таблице в SQL. Каждая Entity содержит набор Attributes — именованных полей с типом данных (String, Integer, Date, Boolean, Data). В отличие от Room, Core Data требует явного выбора типа для каждого атрибута через редактор модели.
Relationship — связь между Entity, аналогичная внешнему ключу в SQL. Core Data поддерживает все типы связей: один-к-одному, один-ко-многим и многие-ко-многим. Для каждой связи настраивается Delete Rule (Cascade, Nullify, Deny) — поведение при удалении связанного объекта.
| Delete Rule | Поведение при удалении | Пример применения |
|---|---|---|
| Cascade | Удаляет все связанные объекты | Удаление заказа вместе с позициями |
| Nullify | Обнуляет обратную связь | Удаление автора без удаления книг |
| Deny | Блокирует удаление, если есть связанные объекты | Защита от удаления категории с товарами |
Выбор Delete Rule критичен для целостности данных: Cascade без проверки может удалить треть всей базы, а Deny — заблокировать операцию с непонятной ошибкой. В продакшн-коде рекомендуется Nullify с ручной обработкой orphan-записей.
В редакторе модели Xcode разработчик может задавать не только Entity и атрибуты, но и constraints (уникальные ограничения), индексы для ускорения запросов и default values для атрибутов. Все изменения модели компилируются в файл .momd, который загружается при инициализации NSPersistentContainer. Версионирование модели (Model Versioning) позволяет поддерживать несколько версий схемы и выполнять миграцию между ними.
NSPersistentContainer — единый объект, управляющий стеком Core Data с iOS 10 и macOS 10.12. Он инкапсулирует NSManagedObjectModel, NSPersistentStoreCoordinator и NSManagedObjectContext, автоматизируя загрузку модели и настройку хранилища. Для более старых версий стек строился вручную, но сейчас это не рекомендуется.
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext
viewContext — главный контекст, привязанный к главному потоку. Все чтения и UI-обновления выполняются через него. Запись данных для производительности рекомендуется выполнять на фоновом контексте дочернего типа с последующей синхронизацией.
Координатор NSPersistentStoreCoordinator связывает модель с физическим хранилищем на диске. Core Data поддерживает несколько типов хранилищ: SQLite (рекомендуемый), Binary и In-Memory. SQLite-хранилище поддерживает миграции, инкрементальный бэкап и устойчивость к сбоям в процессе записи.
NSFetchRequest — объект, описывающий запрос к хранилищу Core Data. Он содержит имя Entity, предикат фильтрации, сортировку и настройки фетчинга. Запрос выполняется через context.fetch(), который возвращает массив NSManagedObject.
let request = NSFetchRequest<User>(entityName: "User")
request.predicate = NSPredicate(format: "age >= %d", 18)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
request.fetchLimit = 50
let results = try context.fetch(request)
NSPredicate поддерживает сложные условия: LIKE, IN, BETWEEN, CONTAINS[c] (регистронезависимый), SUBQUERY для вложенных запросов по связанным Entity. Core Data также поддерживает NSFetchedResultsController — класс для реактивной загрузки данных в UITableView, который автоматически отслеживает изменения и обновляет таблицу анимированными секциями.
Работа с Core Data в многопоточном приложении требует строгого соблюдения правил: NSManagedObject нельзя передавать между потоками напрямую. Каждый поток (или очередь) должен использовать свой контекст. Основной подход — создание дочернего NSManagedObjectContext с приватной очередью (NSPrivateQueueConcurrencyType) для записи и viewContext для чтения.
Дочерний контекст сохраняется в родительский, а затем родительский — в хранилище на диске. Это гарантирует, что изменения не блокируют главный поток и что UI всегда видит консистентное состояние через mergeChanges или автоматическое обновление viewContext при сохранении.
Core Data использует faulting — механизм отложенной загрузки связанных объектов. При фетчинге User без запроса его addresses, связанные Address не загружаются, пока к ним не произойдёт обращение через точечную нотацию. Faulting экономит память и ускоряет загрузку, но может вызывать неожиданные обращения к диску на главном потоке, если не контролировать доступ в фоновых контекстах.
Для эффективной многопоточности используйте NSBatchInsertRequest и NSBatchDeleteRequest для массовой вставки и удаления без загрузки объектов в память — это критично для синхронизации данных с сервером.
Batch-операции выполняются напрямую на уровне NSPersistentStoreCoordinator, минуя контекст и граф объектов. Это позволяет вставить 10 000 записей за несколько миллисекунд без создания 10 000 экземпляров NSManagedObject в памяти. После выполнения batch-запроса контекст необходимо обновить через mergeChangesFromContextDidSaveNotification, чтобы UI отразил новые данные. Apple рекомендует batch-операции для первоначальной загрузки данных и ночной синхронизации с сервером.
Для отслеживания изменений в Core Data используется NSPersistentHistoryTracking — механизм, фиксирующий каждую транзакцию (вставку, обновление, удаление) в отдельной истории. Включение history tracking позволяет синхронизировать данные между различными процессами и приложениями, работающими с одним SQLite-файлом, например между основным приложением и Notification Service Extension. Активация выполняется через NSPersistentStoreDescription с флагом persistentHistoryTrackingKey, а чтение — через NSPersistentHistoryChangeRequest с фильтром по дате и типу транзакции.
Для отладки и профилирования производительности Core Data используется инструмент Core Data Profiler из набора Instruments в Xcode на macOS. Он показывает все операции фетчинга, вставки, удаления и сохранения с длительностью каждой операции и количеством загруженных объектов в таблицах и на графиках временной шкалы. Разработчик может выявить проблемные участки: множественные фетчи одного и того же запроса (отсутствие кэширования), утечки fault-объектов при скролле таблицы или блокировки главного потока из-за синхронной загрузки связанных сущностей. Рекомендуется запускать профилирование на реальном устройстве, а не на симуляторе, так как производительность симулятора не отражает реального поведения приложения на iPhone или iPad.
Часто задаваемые вопросы
Core Data — это не база данных, а слой управления объектами, который может использовать SQLite как хранилище. В отличие от прямого SQLite, Core Data отслеживает изменения объектов, управляет откатами и предоставляет граф объектов с faulting и кэшированием. SQLite даёт больше контроля над запросами, но требует писать SQL и управлять транзакциями вручную.
Core Data поддерживает лёгкую миграцию (Lightweight Migration) для неразрушающих изменений: добавление атрибута, переименование, установка значения по умолчанию. Для сложных изменений создаётся Mapping Model. Lightweight миграция включается флагом shouldMigrateAutomatically в NSPersistentStoreDescription.
Да, Core Data интегрируется со SwiftUI через обёртку @FetchRequest для запросов и @ObservedObject для подписки на изменения. SwiftUI автоматически обновляет View при изменении ManagedObject, что делает Core Data и SwiftUI совместимым стеком для управления состоянием.
Fault — это лёгкая заглушка в графе Core Data, не содержащая данных связанного объекта. При установке fault (через refreshObject:) данные выгружаются из памяти. При обращении к свойству fault автоматически заполняется данными из хранилища — это механизм отложенной загрузки, оптимизирующий использование памяти.
Для тестирования используйте In-Memory тип хранилища: NSPersistentStoreDescription с NSInMemoryStoreType. Контейнер создаётся с моделью из тестового бандла. После каждого теста удаляйте все объекты или пересоздавайте контейнер — это гарантирует изоляцию тестовых кейсов друг от друга.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также