Core Data — кључни појмови, NSManagedObject и архитектура

Аутор: IT Sectr Објављено: 2026-03-11 Време читања: 11 мин

Core Data — Apple фрејмворк за управљање графом објеката у iOS и macOS апликацијама. Он обезбеђује трајно чување података, праћење промена, опозив операција и интеграцију са UI путем NSFetchedResultsController. Према документацији Apple Developer (2025), Core Data није база података — то је ниво објектног моделирања који подразумевано користи SQLite као трајно складиште за учитавање и чување објеката.

Главно

  • Core Data — ORM фрејмворк за iOS/macOS који управља графом објеката и њиховим чувањем у трајном складишту.
  • NSManagedObjectModel — шема података која описује ентитете, атрибуте и релације између објеката у Core Data моделу.
  • NSManagedObjectContext — радна област за креирање, читање, ажурирање и брисање објеката са праћењем промена.
  • NSPersistentContainer — јединствена улазна тачка која обједињује модел, контекст и складиште Core Data у iOS 10+.
  • NSFetchedResultsController — класа за интеграцију Core Data са UITableView/UICollectionView са аутоматским ажурирањем при променама.

Шта је Core Data?

Core Data — је фрејмворк за управљање графом објеката и перзистентношћу, део Cocoa Touch SDK компаније Apple. Он пружа објектно-оријентисани интерфејс за рад са подацима: програмер оперише ентитетима (Entity), атрибутима и релацијама (Relationship), а Core Data претвара ове објекте у записе релационе базе података испод хаубе.

Core Data је представљен у Mac OS X 10.4 Tiger (2005) за macOS и пренесен у iOS 3.0 (2009). Током више од 20 година, фрејмворк је еволуирао од једноставног слоја апстракције изнад SQLite до потпуног стека са подршком за облачну синхронизацију кроз NSPersistentCloudKitContainer, вишенитност кроз аутоматско управљање контекстима и асинхроно учитавање кроз Swift Concurrency.

Према анкети iOS програмера из Slack Community (2025), Core Data се користи у 68% комерцијалних iOS апликација за локално чување података. Упркос критикама због сложености и вишеслојности, фрејмворк остаје стандард за Apple апликације захваљујући чврстој интеграцији са системом, нултој цени (уграђен у SDK) и подршци за iCloud синхронизацију.

Core Data није база података

Честа заблуда — сматрати Core Data базом података. Фрејмворк не извршава SQL упите директно и није систем за управљање базама података. Core Data је слој за управљање објектима (object graph management) који може користити SQLite, Binary или In-Memory складиште за перзистентност. Аналогија: Core Data је као ORM попут Hibernate или Entity Framework, али за Apple екосистем, а SQLite испод њега — као MySQL испод Hibernate.

Архитектура Core Data: стекови и компоненте

Core Data стек се састоји од четири међусобно повезане компоненте: NSManagedObjectModel (шема података), NSPersistentStoreCoordinator (координатор складишта), NSManagedObjectContext (радни контекст) и NSPersistentContainer (јединствени контејнер који обједињује све три од iOS 10). NSPersistentContainer аутоматизује креирање и конфигурацију стека.

Свака компонента обавља строго дефинисану функцију. NSManagedObjectModel учитава .xcdatamodeld датотеку са описом ентитета. NSPersistentStoreCoordinator повезује модел са физичком датотеком складишта (SQLite). NSManagedObjectContext обезбеђује привремену област за рад са објектима. Контејнер обједињује све у један позив иницијализације.

Типови Core Data складишта

SQLite (NSSQLiteStoreType) — стандардно складиште које се користи у већини апликација. Подаци се чувају у једној .sqlite датотеци са подршком за ACID трансакције. Binary (NSBinaryStoreType) — складиште у бинарном формату за мале скупове података (до неколико стотина објеката). In-Memory (NSInMemoryStoreType) — привремено складиште у оперативној меморији без чувања на диск, користи се за тестове и кеш.

Тип складиштаФорматПерформансеКада користити
SQLite.sqliteВисокеСтандардни избор за production
Binary.binaryСредњеМали скупови података
In-MemoryRAMМаксималнеТестови, кеш, привремени подаци
CloudKitiCloudЗависе од мрежеСинхронизација између уређаја

Избор складишта се поставља једним редом при иницијализацији NSPersistentStoreDescription. Програмер може пребацити складиште са SQLite на In-Memory за unit тестове или на CloudKit за iCloud синхронизацију без промене кода за рад са објектима — Core Data апстрахује разлику између типова складишта путем јединственог API контекста.

NSManagedObject и NSManagedObjectContext

NSManagedObject — основна класа за све Core Data објекте, која представља један запис ентитета. Сваки managed object има јединствени NSManagedObjectID (трајни идентификатор), везан је за контекст и прати своје промене кроз KVO (Key-Value Observing). Програмер креира подкласе NSManagedObject за дефинисање типизованих својстава ентитета.

NSManagedObjectContext — централна компонента Core Data која обезбеђује радну област за све операције са објектима. Контекст прати додавања, брисања и измене објеката (change tracking), подржава опозив операција кроз undoManager и аутоматски спаја промене из других контекста при пријему обавештења о чувању.

Безбедност нити контекста

Правило приватних редова: NSManagedObjectContext се креира са типом .privateQueueConcurrencyType или .mainQueueConcurrencyType. Главни контекст је везан за главну UI нит, приватни контексти се извршавају на позадинским редовима. Сваки контекст се сме користити само на свом реду — приступ managed објекту са друге нити изазива краш. parentContext омогућава организовање хијерархије контекста за асинхроно писање.

swift
struct CoreDataStack {
    let container: NSPersistentContainer

    init(name: String) {
        container = NSPersistentContainer(name: name)
        container.loadPersistentStores { _, error in
            if let error = error {
                fatalError("Failed to load store: \(error)")
            }
        }
        container.viewContext.automaticallyMergesChangesFromParent = true
    }

    func backgroundContext() -> NSManagedObjectContext {
        let context = container.newBackgroundContext()
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        return context
    }
}

NSPersistentContainer аутоматски креира viewContext (main queue) и обезбеђује newBackgroundContext() за позадинске операције. Својство automaticallyMergesChangesFromParent = true чини да viewContext аутоматски преузима промене из позадинских контекста при њиховом чувању, ажурирајући UI без ручног поновног упита података.

Persistent Store и веза са SQLite

NSPersistentStoreCoordinator управља физичким складиштем података: отвара датотеку, креира SQLite табеле на основу модела, извршава миграције при промени шеме. При иницијализацији NSPersistentStoreDescription са типом NSSQLiteStoreType, Core Data креира SQLite датотеку са шемом која одговара .xcdatamodeld моделу.

Core Data не користи стандардне SQL упите кроз SELECT/INSERT/UPDATE. Уместо тога, генерише интерне SQL команде на основу модела и упита кроз NSFetchRequest. Програмер може укључити логирање SQL-а кроз аргумент покретања -com.apple.CoreData.SQLDebug 1 за дебаговање перформанси упита.

Core Data миграције

Лагана миграција (Lightweight Migration) — аутоматски процес ажурирања SQLite шеме при додавању нових атрибута, промени optional/required или преименовању помоћу renamingID. Тешка миграција је потребна при коренитим променама шеме, као што су спајање или раздвајање ентитета, и извршава се кроз прилагођени NSMigrationManager.

swift
let description = NSPersistentStoreDescription()
description.url = FileManager.default
    .urls(for: .documentDirectory, in: .userDomainMask)
    .first?
    .appendingPathComponent("Model.sqlite")
description.setOption(true as NSNumber,
    forKey: NSMigratePersistentStoresAutomaticallyOption)
description.setOption(true as NSNumber,
    forKey: NSInferMappingModelAutomaticallyOption)

let container = NSPersistentContainer(name: "AppModel")
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { _, error in
    if let error = error { print("Migration error: \(error)") }
}

Подешавање аутоматске миграције кроз NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption омогућава Core Data да самостално ажурира SQLite датотеку при додавању атрибута или ентитета у новој верзији модела. Ако миграција није могућа, store coordinator баца грешку са описом разлога — програмер мора да имплементира прилагођену миграцију кроз NSMigrationManager.

Core Data у пракси: код и примери

NSFetchRequest — основни алат за преузимање објеката из Core Data. Упит садржи име ентитета, предикат (филтер), сортирања, лимит и помак (offset). Резултат се враћа као низ NSManagedObject или типизованих подкласа. NSPredicate подржава сложене услове са AND, OR, IN, LIKE и подупитима.

NSBatchDeleteRequest — ефикасан начин масовног брисања објеката без учитавања сваког у меморију. Упит се извршава на нивоу SQLite, заобилазећи managed object context, и само ажурира контекст након завршетка. Слични batch упити постоје за ажурирање (NSBatchUpdateRequest) и уметање (NSBatchInsertRequest).

Пример CRUD операција

CRUD (Create, Read, Update, Delete) у Core Data се извршава кроз методе контекста: insert, fetch, save и delete. Све промене су привремене до позива context.save() — метод чува промене у трајном SQLite складишту. При грешци чувања, контекст остаје у измењеном стању за поновни покушај.

swift
let context = container.viewContext

// Креирај
let user = User(context: context)
user.id = 42
user.name = "Alice"

// Читај
let request = User.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS %@", "Ali")
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let results = try context.fetch(request)

// Ажурирај
results.first?.name = "Alice Updated"

// Обриши
if let first = results.first { context.delete(first) }

// Сачувај
try context.save()

Чување контекста (context.save()) — критична операција. Ако чување није позвано, све промене остају само у меморији. Контекст прати стање hasChanges, које се може проверити пре чувања. За позадинске операције користите newBackgroundContext са сопственим чувањем, а за UI — viewContext са аутоматским чувањем по тајмеру или при одласку апликације у позадину.

Најбоље праксе Core Data

Прва пракса — користите NSPersistentCloudKitContainer за синхронизацију података између уређаја корисника путем iCloud-а. Облачна синхронизација се укључује додавањем CloudKit опције опису складишта. Core Data аутоматски управља конфликтима при синхронизацији и спаја промене са других уређаја.

Друга пракса — избегавајте fetchRequest без предиката на великим табелама. Сваки безусловни упит учитава све објекте ентитета у меморију, што доводи до високе потрошње RAM-а и успоравања UI-ја. Увек користите предикате и лимите. За пагинацију примените fetchLimit и fetchOffset у NSFetchRequest.

Трећа пракса — подесите mergePolicy за решавање конфликата при вишенитном приступу. NSMergeByPropertyObjectTrumpMergePolicy ажурира конфликтна својства из последњег сачуваног контекста. NSRollbackMergePolicy поништава промене текућег контекста при конфликту. Избор политике зависи од пословне логике апликације.

Четврта пракса — користите NSFetchedResultsController за интеграцију са табелама и колекцијама. Он се аутоматски претплаћује на обавештења NSManagedObjectContextDidSave, учитава само потребне објекте (faulting) и обавештава делегата о уметањима, брисањима и премештањима са одговарајућим индексним путањама за анимацију UITableView.

Перформансе: prefetching и faulting

Faulting — механизам лењог учитавања Core Data објеката. Managed object враћен fetch упитом је у стању fault — његови атрибути нису потпуно учитани, већ само идентификатор. Потпуно учитавање (fire fault) се дешава при првом приступу било ком атрибуту. Relationship prefetching (setRelationshipKeyPathsForPrefetching) учитава повезане објекте унапред, избегавајући N+1 упите.

swift
extension UserRepository {
    func fetchUsersWithPosts() throws -> [User] {
        let request = User.fetchRequest()
        request.predicate = NSPredicate(format: "isActive == YES")
        request.relationshipKeyPathsForPrefetching = ["posts"]
        request.returnsObjectsAsFaults = false
        request.fetchBatchSize = 20

        let context = container.viewContext
        return try context.fetch(request)
    }
}

fetchBatchSize = 20 приморава Core Data да учитава податке у порцијама од по 20 објеката (за приказ на екрану), без учитавања целе табеле одједном. Заставица returnsObjectsAsFaults = false гарантује да су атрибути свих корисника одмах учитани, што је корисно при директном приказивању. Prefetching релације "posts" избегава засебне упите за сваког корисника при приступу постовима.

Често постављана питања

Core Data — да ли је то база података?

Не, Core Data је фрејмворк за управљање графом објеката. Он пружа API за рад са објектима, праћење промена и њихово чување. Базу података испод Core Data (подразумевано SQLite) не треба мешати са самим фрејмворком. Core Data је ORM, а не систем за управљање базама података.

Може ли се Core Data користити без SQLite?

Да, Core Data подржава три типа складишта: SQLite, Binary и In-Memory. Избор складишта се поставља кроз NSPersistentStoreDescription. In-Memory складиште не чува податке на диск и погодно је за unit тестове. Binary складиште је застарели формат за компактне скупове објеката.

Како пребацити Core Data на нову верзију модела?

За лаку миграцију укључите NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption. За сложене промене креирајте Mapping Model (.xcmappingmodel) кроз Xcode. CloudKit складиште (NSPersistentCloudKitContainer) подржава миграције аутоматски при синхронизацији шеме са iCloud сервером.

По чему се Core Data разликује од SwiftData?

SwiftData — нови Apple фрејмворк (iOS 17+), изграђен изнад Core Data коришћењем Swift Macros и Swift Concurrency. SwiftData је једноставнији у синтакси: ентитети се описују макроом @Model, контекст — @Environment(\.modelContext). Испод хаубе SwiftData користи исти Core Data стек и SQLite.

Како дебаговати споре Core Data упите?

Укључите аргумент покретања -com.apple.CoreData.SQLDebug 1 — Core Data ће приказивати све SQL упите и њихово трајање у Xcode конзоли. За профилисање користите Instruments са Core Data шаблоном, који показује број fault упита, учитавање објеката и време чувања контекста.

Завршни преглед

  • Core Data — фрејмворк за управљање графом објеката и перзистентношћу за iOS и macOS, који користи SQLite као стандардно складиште.
  • Core Data стек укључује NSManagedObjectModel, NSPersistentStoreCoordinator, NSManagedObjectContext и NSPersistentContainer за јединствену конфигурацију.
  • NSManagedObjectContext — радна област са праћењем промена, подршком за опозив и аутоматским спајањем из позадинских контекста.
  • NSFetchRequest са NSPredicate и prefetching-ом — основни алат за преузимање са оптимизацијом кроз batch size и faulting.
  • Lightweight Migration аутоматски ажурира SQLite шему при додавању атрибута и ентитета Core Data у новој верзији модела.
  • NSPersistentCloudKitContainer додаје iCloud синхронизацију између уређаја корисника са аутоматским решавањем конфликата.
  • Препорука — користите Core Data за iOS апликације са хијерархијским објектним моделима, а за једноставно локално складиштење размотрите GRDB или SwiftData.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође