Core Data — що це таке, модель даних та як працює

Автор: IT Sectr Опубліковано: 2026-05-04 Час читання: 8 хв

Core Data — це фреймворк керування даними від Apple, що надає об'єктно-реляційне відображення для iOS, macOS, tvOS та watchOS. Він автоматизує збереження, вилучення та фільтрацію об'єктів у застосунку, працюючи поверх SQLite, XML або бінарного сховища. Згідно з Apple Core Data Documentation, фреймворк використовує концепції Managed Object Context та NSPersistentContainer для керування стеком персистентності.

Головне

  • Core Data — фреймворк Apple для об'єктно-реляційного керування даними в застосунках.
  • NSManagedObjectModel — опис схеми даних: Entity, Attributes та Relationships.
  • NSManagedObject — об'єкт, що відповідає одному запису в сховищі Core Data.
  • NSManagedObjectContext — робоча область для створення, читання та збереження об'єктів.
  • NSPersistentContainer — єдиний стек, що об'єднує модель, контекст та координатор сховища.

Що таке Core Data та його роль в iOS

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() контекст фіксує всі зміни однією транзакцією в постійному сховищі, гарантуючи атомарність та консистентність даних.

Модель даних: Entity, Attributes, Relationships

Модель даних Core Data визначається у файлі .xcdatamodeld — візуальному редакторі Xcode, де описуються всі Entity, їхні атрибути та зв'язки. При компіляції модель серіалізується в .momd та завантажується через NSManagedObjectModel.

Entity та Attributes

Entity — це опис типу даних, аналогічний таблиці в SQL. Кожна Entity містить набір Attributes — іменованих полів із типом даних (String, Integer, Date, Boolean, Data). На відміну від Room, Core Data вимагає явного вибору типу для кожного атрибута через редактор моделі.

Relationships

Relationship — зв'язок між Entity, аналогічний зовнішньому ключу в SQL. Core Data підтримує всі типи зв'язків: один-до-одного, один-до-багатьох та багато-до-багатьох. Для кожного зв'язку налаштовується Delete Rule (Cascade, Nullify, Deny) — поведінка при видаленні пов'язаного об'єкта.

Delete RuleПоведінка при видаленніПриклад застосування
CascadeВидаляє всі пов'язані об'єктиВидалення замовлення разом із позиціями
NullifyОбнуляє зворотний зв'язокВидалення автора без видалення книг
DenyБлокує видалення, якщо є пов'язані об'єктиЗахист від видалення категорії з товарами

Вибір Delete Rule критичний для цілісності даних: Cascade без перевірки може видалити третину бази даних, а Deny — заблокувати операцію з незрозумілою помилкою. У продакшн-коді рекомендується Nullify з ручним обробленням осиротілих записів.

У редакторі моделі Xcode розробник може задавати не лише Entity та атрибути, але й constraints (унікальні обмеження), індекси для прискорення запитів та значення за замовчуванням для атрибутів. Усі зміни моделі компілюються у файл .momd, який завантажується при ініціалізації NSPersistentContainer. Версіонування моделі (Model Versioning) дозволяє підтримувати кілька версій схеми та виконувати міграцію між ними.

Стек Core Data: PersistentContainer та Context

NSPersistentContainer — єдиний об'єкт, що керує стеком Core Data з iOS 10 та macOS 10.12. Він інкапсулює NSManagedObjectModel, NSPersistentStoreCoordinator та NSManagedObjectContext, автоматизуючи завантаження моделі та налаштування сховища. Для старіших версій стек будувався вручну, але зараз це не рекомендується.

swift
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
    if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext

viewContext — головний контекст, прив'язаний до головного потоку. Усі читання та оновлення інтерфейсу виконуються через нього. Запис даних для продуктивності рекомендується виконувати на фоновому дочірньому контексті з подальшою синхронізацією.

NSPersistentStoreCoordinator

Координатор NSPersistentStoreCoordinator пов'язує модель із фізичним сховищем на диску. Core Data підтримує кілька типів сховищ: SQLite (рекомендований), Binary та In-Memory. SQLite-сховище підтримує міграції, інкрементальне резервне копіювання та стійкість до збоїв у процесі запису.

NSFetchRequest та робота з даними

NSFetchRequest — об'єкт, що описує запит до сховища Core Data. Він містить ім'я Entity, предикат фільтрації, сортування та налаштування отримання. Запит виконується через context.fetch(), який повертає масив NSManagedObject.

swift
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 в багатопотоковому середовищі

Робота з Core Data в багатопотоковому застосунку вимагає суворого дотримання правил: NSManagedObject не можна передавати між потоками безпосередньо. Кожен потік (або черга) повинен використовувати свій контекст. Основний підхід — створення дочірнього NSManagedObjectContext з приватною чергою (NSPrivateQueueConcurrencyType) для запису та viewContext для читання.

Дочірній контекст зберігається в батьківський, а потім батьківський — у сховище на диску. Це гарантує, що зміни не блокують головний потік і що інтерфейс завжди бачить консистентний стан через mergeChanges або автоматичне оновлення viewContext при збереженні.

Core Data використовує faulting — механізм відкладеного завантаження пов'язаних об'єктів. При отриманні User без запиту його адрес, пов'язані Address не завантажуються, доки до них не відбудеться звернення через крапкову нотацію. Faulting економить пам'ять і прискорює завантаження, але може викликати неочікувані звернення до диску на головному потоці, якщо не контролювати доступ у фонових контекстах.

Для ефективної багатопотоковості використовуйте NSBatchInsertRequest та NSBatchDeleteRequest для масового вставлення та видалення без завантаження об'єктів у пам'ять — це критично для синхронізації даних із сервером.

Пакетні операції виконуються безпосередньо на рівні NSPersistentStoreCoordinator, минаючи контекст та граф об'єктів. Це дозволяє вставити 10 000 записів за кілька мілісекунд без створення 10 000 екземплярів NSManagedObject у пам'яті. Після виконання пакетного запиту контекст необхідно оновити через mergeChangesFromContextDidSaveNotification, щоб інтерфейс відобразив нові дані. Apple рекомендує пакетні операції для початкового завантаження даних та нічної синхронізації з сервером.

Для відстеження змін у 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?

Core Data — це не база даних, а рівень керування об'єктами, який може використовувати SQLite як сховище. На відміну від прямого SQLite, Core Data відстежує зміни об'єктів, керує відкочуванням та надає граф об'єктів із faulting та кешуванням. SQLite дає більше контролю над запитами, але вимагає писати SQL та керувати транзакціями вручну.

Як виконати міграцію схеми Core Data?

Core Data підтримує легку міграцію (Lightweight Migration) для незворушливих змін: додавання атрибута, перейменування, встановлення значення за замовчуванням. Для складних змін створюється Mapping Model. Lightweight міграція вмикається прапорцем shouldMigrateAutomatically в NSPersistentStoreDescription.

Чи можна використовувати Core Data з SwiftUI?

Так, Core Data інтегрується зі SwiftUI через обгортку @FetchRequest для запитів та @ObservedObject для підписки на зміни. SwiftUI автоматично оновлює View при зміні ManagedObject, що робить Core Data та SwiftUI сумісним стеком для керування станом.

Що таке fault у Core Data?

Fault — це легка заглушка в графі Core Data, що не містить даних пов'язаного об'єкта. При встановленні fault (через refreshObject:) дані вивантажуються з пам'яті. При зверненні до властивості fault автоматично заповнюється даними зі сховища — це механізм відкладеного завантаження, який оптимізує використання пам'яті.

Як тестувати код Core Data?

Для тестування використовуйте In-Memory тип сховища: NSPersistentStoreDescription з NSInMemoryStoreType. Контейнер створюється з моделлю з тестового бандла. Після кожного тесту видаляйте всі об'єкти або перестворюйте контейнер — це гарантує ізоляцію тестових кейсів один від одного.

Підсумки

  • Core Data — фреймворк керування об'єктним графом, що використовує SQLite як сховище за замовчуванням.
  • NSManagedObjectModel описує схему: Entity, Attributes, Relationships та Delete Rules.
  • NSPersistentContainer об'єднує модель, координатор та viewContext в єдиний стек.
  • NSFetchRequest з NSPredicate та NSSortDescriptor формує гнучкі запити до сховища.
  • Багатопотоковість вимагає окремих контекстів: дочірній контекст для запису та viewContext для читання.
  • Faulting відкладає завантаження пов'язаних об'єктів до першого звернення, економлячи пам'ять.
  • Lightweight Migration автоматично обробляє незворушливі зміни схеми без втрати даних.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також