Core Data — ce este, modelul de date și cum funcționează

Autor: IT Sectr Publicat: 2026-05-04 Timp de citire: 8 min

Core Data este un framework de gestionare a datelor de la Apple, care oferă mapare obiect-relațională pentru iOS, macOS, tvOS și watchOS. Automatizează salvarea, extragerea și filtrarea obiectelor în aplicație, funcționând pe SQLite, XML sau stocare binară. Conform Apple Core Data Documentation, framework-ul utilizează conceptele Managed Object Context și NSPersistentContainer pentru gestionarea stivei de persistență.

Principalele

  • Core Data — framework Apple pentru gestionarea obiectual-relațională a datelor în aplicații.
  • NSManagedObjectModel — descrierea schemei datelor: Entity, Attributes și Relationships.
  • NSManagedObject — obiect corespunzător unei înregistrări în stocarea Core Data.
  • NSManagedObjectContext — spațiu de lucru pentru crearea, citirea și salvarea obiectelor.
  • NSPersistentContainer — stivă unitară care combină modelul, contextul și coordonatorul de stocare.

Ce este Core Data și rolul său în iOS

Core Data — este un framework de gestionare a grafului de obiecte și a persistenței, care face parte din Cocoa Touch. Contrar concepției greșite răspândite, Core Data nu este o bază de date, ci un strat de gestionare a obiectelor care poate utiliza SQLite ca unul dintre depozite. Sarcina principală a Core Data este de a urmări modificările obiectelor, de a gestiona ciclul lor de viață și de a sincroniza starea cu discul.

Framework-ul oferă un graf de obiecte, în care fiecare Managed Object este urmărit de context pentru modificări. La salvarea contextului, toate obiectele modificate, adăugate și șterse sunt confirmate în stocarea persistentă printr-o singură tranzacție. Acest lucru eliberează dezvoltatorul de scrierea interogărilor SQL și gestionarea manuală a tranzacțiilor.

Conform statisticilor Swift Developer Survey (2025), Core Data este utilizat în 52% din aplicațiile iOS care lucrează cu date locale. În ciuda apariției alternativelor moderne (SwiftData, Realm), Core Data rămâne principalul framework în proiectele Apple existente datorită maturității și integrării profunde cu sistemul.

Utilizați Core Data pentru proiecte cu un model de date de complexitate medie, unde sunt necesare relații între obiecte, anularea modificărilor și cache automat prin mecanismul faulting.

Arhitectura Core Data este construită în jurul conceptului de Managed Object Context — un spațiu de lucru care urmărește toate modificările obiectelor. Contextul suportă anularea (undo/redo) prin NSUndoManager încorporat, ceea ce permite implementarea ciornelor și anularea acțiunilor fără salvarea manuală a instantaneelor de stare. La apelarea save(), contextul confirmă toate modificările printr-o singură tranzacție în stocarea persistentă, garantând atomicitatea și consistența datelor.

Modelul de date: Entity, Attributes, Relationships

Modelul de date Core Data este definit în fișierul .xcdatamodeld — editorul vizual Xcode, unde sunt descrise toate Entitățile, atributele și relațiile lor. La compilare, modelul este serializat în .momd și încărcat prin NSManagedObjectModel.

Entity și Attributes

Entity — este o descriere a tipului de date, similară unui tabel în SQL. Fiecare Entity conține un set de Attributes — câmpuri denumite cu un tip de date (String, Integer, Date, Boolean, Data). Spre deosebire de Room, Core Data necesită alegerea explicită a tipului pentru fiecare atribut prin editorul de model.

Relationships

Relationship — relație între Entități, similară unei chei externe în SQL. Core Data suportă toate tipurile de relații: unu-la-unu, unu-la-mulți și mulți-la-mulți. Pentru fiecare relație se configurează Delete Rule (Cascade, Nullify, Deny) — comportamentul la ștergerea obiectului asociat.

Delete RuleComportament la ștergereExemplu de utilizare
CascadeȘterge toate obiectele asociateȘtergerea comenzii împreună cu pozițiile
NullifyAnulează relația inversăȘtergerea autorului fără ștergerea cărților
DenyBlochează ștergerea dacă există obiecte asociateProtecția împotriva ștergerii categoriei cu produse

Alegerea Delete Rule este critică pentru integritatea datelor: Cascade fără verificare poate șterge o treime din bază, iar Deny poate bloca operația cu o eroare de neînțeles. În codul de producție, se recomandă Nullify cu procesarea manuală a înregistrărilor orfane.

În editorul de model Xcode, dezvoltatorul poate seta nu doar Entity și atribute, ci și constraints (restricții de unicitate), indecși pentru accelerarea interogărilor și default values pentru atribute. Toate modificările modelului sunt compilate în fișierul .momd, care este încărcat la inițializarea NSPersistentContainer. Versionarea modelului (Model Versioning) permite menținerea mai multor versiuni ale schemei și efectuarea migrării între ele.

Stiva Core Data: PersistentContainer și Context

NSPersistentContainer — un obiect unitar care gestionează stiva Core Data de la iOS 10 și macOS 10.12. Acesta încapsulează NSManagedObjectModel, NSPersistentStoreCoordinator și NSManagedObjectContext, automatizând încărcarea modelului și configurarea stocării. Pentru versiunile mai vechi, stiva se construia manual, dar acum acest lucru nu este recomandat.

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

viewContext — contextul principal legat de firul principal. Toate citirile și actualizările UI se efectuează prin acesta. Scrierea datelor pentru performanță se recomandă a fi efectuată într-un context copil cu coadă privată și sincronizare ulterioară.

NSPersistentStoreCoordinator

Coordonatorul NSPersistentStoreCoordinator leagă modelul de stocarea fizică pe disc. Core Data suportă mai multe tipuri de stocări: SQLite (recomandat), Binary și In-Memory. Stocarea SQLite suportă migrări, backup incremental și rezistență la erori în timpul procesului de scriere.

NSFetchRequest și lucrul cu datele

NSFetchRequest — un obiect care descrie o interogare către stocarea Core Data. Conține numele Entității, predicatul de filtrare, sortarea și setările de preluare. Interogarea se execută prin context.fetch(), care returnează un array de 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 suportă condiții complexe: LIKE, IN, BETWEEN, CONTAINS[c] (fără diferențiere între majuscule și minuscule), SUBQUERY pentru interogări imbricate pe Entități asociate. Core Data suportă de asemenea NSFetchedResultsController — o clasă pentru încărcarea reactivă a datelor în UITableView, care urmărește automat modificările și actualizează tabelul cu secțiuni animate.

Core Data în mediu multi-thread

Lucrul cu Core Data într-o aplicație multi-thread necesită respectarea strictă a regulilor: NSManagedObject nu poate fi transmis direct între fire. Fiecare fir (sau coadă) trebuie să utilizeze propriul context. Abordarea principală — crearea unui NSManagedObjectContext copil cu o coadă privată (NSPrivateQueueConcurrencyType) pentru scriere și viewContext pentru citire.

Contextul copil se salvează în părinte, iar apoi părintele — în stocarea pe disc. Aceasta garantează că modificările nu blochează firul principal și că UI vede întotdeauna o stare consistentă prin mergeChanges sau actualizarea automată a viewContext la salvare.

Core Data utilizează faulting — un mecanism de încărcare întârziată a obiectelor asociate. La preluarea User fără a solicita addresses-ul său, Address-urile asociate nu se încarcă până când nu se face o referire la ele prin notația cu punct. Faulting economisește memoria și accelerează încărcarea, dar poate cauza accesări neașteptate la disc pe firul principal dacă accesul nu este controlat în contextele de fundal.

Pentru multi-threading eficient, utilizați NSBatchInsertRequest și NSBatchDeleteRequest pentru inserarea și ștergerea în masă fără încărcarea obiectelor în memorie — acest lucru este critic pentru sincronizarea datelor cu serverul.

Operațiile batch se execută direct la nivelul NSPersistentStoreCoordinator, ocolind contextul și graful de obiecte. Acest lucru permite inserarea a 10.000 de înregistrări în câteva milisecunde fără a crea 10.000 de instanțe NSManagedObject în memorie. După executarea interogării batch, contextul trebuie actualizat prin mergeChangesFromContextDidSaveNotification pentru ca UI să reflecte noile date. Apple recomandă operațiile batch pentru încărcarea inițială a datelor și sincronizarea nocturnă cu serverul.

Pentru urmărirea modificărilor în Core Data se utilizează NSPersistentHistoryTracking — un mecanism care înregistrează fiecare tranzacție (inserare, actualizare, ștergere) într-un istoric separat. Activarea history tracking permite sincronizarea datelor între diferite procese și aplicații care lucrează cu același fișier SQLite, de exemplu între aplicația principală și Notification Service Extension. Activarea se face prin NSPersistentStoreDescription cu flag-ul persistentHistoryTrackingKey, iar citirea — prin NSPersistentHistoryChangeRequest cu filtru după dată și tipul tranzacției.

Pentru depanarea și profilarea performanței Core Data se utilizează instrumentul Core Data Profiler din setul Instruments din Xcode pe macOS. Acesta arată toate operațiile de preluare, inserare, ștergere și salvare cu durata fiecărei operații și numărul de obiecte încărcate în tabele și pe graficele axei temporale. Dezvoltatorul poate identifica zonele problematice: preluări multiple ale aceleiași interogări (lipsa cache-ului), scurgeri de obiecte fault la derularea tabelului sau blocarea firului principal din cauza încărcării sincrone a entităților asociate. Se recomandă efectuarea profilării pe un dispozitiv real, nu pe simulator, deoarece performanța simulatorului nu reflectă comportamentul real al aplicației pe iPhone sau iPad.

Întrebări frecvente

Cu ce se deosebește Core Data de SQLite?

Core Data — nu este o bază de date, ci un strat de gestionare a obiectelor care poate utiliza SQLite ca stocare. Spre deosebire de SQLite direct, Core Data urmărește modificările obiectelor, gestionează anulările și oferă un graf de obiecte cu faulting și cache. SQLite oferă mai mult control asupra interogărilor, dar necesită scrierea SQL și gestionarea manuală a tranzacțiilor.

Cum se execută migrarea schemei Core Data?

Core Data suportă migrarea ușoară (Lightweight Migration) pentru modificări nedistructive: adăugarea unui atribut, redenumirea, setarea unei valori implicite. Pentru modificări complexe se creează un Mapping Model. Migrarea ușoară se activează prin flag-ul shouldMigrateAutomatically în NSPersistentStoreDescription.

Se poate utiliza Core Data cu SwiftUI?

Da, Core Data se integrează cu SwiftUI prin wrapper-ul @FetchRequest pentru interogări și @ObservedObject pentru abonarea la modificări. SwiftUI actualizează automat View la modificarea ManagedObject, ceea ce face ca Core Data și SwiftUI să fie o stivă compatibilă pentru gestionarea stării.

Ce este fault în Core Data?

Fault — este un substituent ușor în graful Core Data, care nu conține datele obiectului asociat. La setarea fault (prin refreshObject:) datele sunt descărcate din memorie. La accesarea proprietății, fault se completează automat cu datele din stocare — acesta este un mecanism de încărcare întârziată care optimizează utilizarea memoriei.

Cum se testează codul Core Data?

Pentru testare utilizați tipul de stocare In-Memory: NSPersistentStoreDescription cu NSInMemoryStoreType. Containerul se creează cu modelul din pachetul de test. După fiecare test, ștergeți toate obiectele sau recreați containerul — aceasta garantează izolarea cazurilor de test unul de celălalt.

Rezumat

  • Core Data — framework de gestionare a grafului de obiecte, care utilizează SQLite ca stocare implicită.
  • NSManagedObjectModel descrie schema: Entity, Attributes, Relationships și Delete Rules.
  • NSPersistentContainer combină modelul, coordonatorul și viewContext într-o stivă unitară.
  • NSFetchRequest cu NSPredicate și NSSortDescriptor formează interogări flexibile către stocare.
  • Multi-threading-ul necesită contextele separate: context copil pentru scriere și viewContext pentru citire.
  • Faulting amână încărcarea obiectelor asociate până la prima accesare, economisind memoria.
  • Lightweight Migration gestionează automat modificările nedistructive ale schemei fără pierderea datelor.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și