Core Data — Schlüsselkonzepte, NSManagedObject und Architektur

Autor: IT Sectr Veröffentlicht: 2026-03-11 Lesezeit: 11 Min.

Core Data ist ein Apple-Framework zur Verwaltung eines Objektgraphen in iOS- und macOS-Anwendungen. Es bietet Datenpersistenz, Änderungsverfolgung, Rückgängig-Operationen und UI-Integration über NSFetchedResultsController. Laut Apple Developer-Dokumentation (2025) ist Core Data keine Datenbank — es ist eine Objektmodellierungsschicht, die standardmäßig SQLite als persistenten Speicher zum Laden und Speichern von Objekten verwendet.

Das Wichtigste

  • Core Data ist ein ORM-Framework für iOS/macOS, das einen Objektgraphen verwaltet und in einem Speicher persistiert.
  • NSManagedObjectModel ist das Datenschema, das Entitäten, Attribute und Beziehungen in einem Core Data-Modell beschreibt.
  • NSManagedObjectContext ist ein Arbeitsbereich zum Erstellen, Lesen, Aktualisieren und Löschen von Objekten mit Änderungsverfolgung.
  • NSPersistentContainer ist ein einheitlicher Einstiegspunkt, der Modell, Kontext und Speicher in iOS 10+ kapselt.
  • NSFetchedResultsController integriert Core Data mit UITableView/UICollectionView mit automatischer Aktualisierung bei Änderungen.

Was ist Core Data?

Core Data ist ein Framework zur Objektgraphenverwaltung und Persistenz, das Teil des Cocoa Touch SDK von Apple ist. Es bietet eine objektorientierte Schnittstelle zur Arbeit mit Daten: Der Entwickler arbeitet mit Entitäten, Attributen und Beziehungen, während Core Data diese Objekte unter der Haube in relationale Datenbankdatensätze umwandelt.

Core Data wurde in Mac OS X 10.4 Tiger (2005) für macOS eingeführt und auf iOS 3.0 (2009) portiert. In über 20 Jahren hat sich das Framework von einer einfachen Abstraktionsebene über SQLite zu einem vollwertigen Stack mit Cloud-Synchronisation über NSPersistentCloudKitContainer, Multithreading durch automatische Kontextverwaltung und asynchronem Laden via Swift Concurrency entwickelt.

Laut einer iOS-Entwicklerumfrage der Slack Community (2025) wird Core Data in 68% der kommerziellen iOS-Anwendungen zur lokalen Datenspeicherung verwendet. Trotz Kritik an Komplexität und Mehrschichtigkeit bleibt das Framework der Standard für Apple-Anwendungen dank enger Systemintegration, Nullkosten (im SDK enthalten) und iCloud-Synchronisationsunterstützung.

Core Data ist keine Datenbank

Ein häufiges Missverständnis ist, Core Data für eine Datenbank zu halten. Das Framework führt keine SQL-Abfragen direkt aus und ist kein DBMS. Core Data ist eine Objektgraphenverwaltungsschicht, die SQLite, Binary oder In-Memory-Speicher für die Persistenz nutzen kann. Analogie: Core Data ist wie Hibernate oder Entity Framework, aber für das Apple-Ökosystem, und SQLite darunter ist wie MySQL unter Hibernate.

Core Data-Architektur: Stacks und Komponenten

Der Core Data-Stack besteht aus vier miteinander verbundenen Komponenten: NSManagedObjectModel (Datenschema), NSPersistentStoreCoordinator (Speicherkoordinator), NSManagedObjectContext (Arbeitskontext) und NSPersistentContainer (ein einheitlicher Container, der alle drei seit iOS 10 vereint). NSPersistentContainer automatisiert die Stack-Erstellung und -Konfiguration.

Jede Komponente erfüllt eine streng definierte Funktion. NSManagedObjectModel lädt die .xcdatamodeld-Datei mit Entitätsbeschreibungen. NSPersistentStoreCoordinator verbindet das Modell mit der physischen Speicherdatei (SQLite). NSManagedObjectContext bietet einen temporären Bereich für die Arbeit mit Objekten. Der Container vereint alles in einem einzigen Initialisierungsaufruf.

Core Data-Speichertypen

SQLite (NSSQLiteStoreType) ist der in den meisten Anwendungen verwendete Standardspeicher. Daten werden in einer einzigen .sqlite-Datei mit ACID-Transaktionsunterstützung gespeichert. Binary (NSBinaryStoreType) ist ein Binärformat-Speicher für kleine Datensätze (bis zu einigen hundert Objekten). In-Memory (NSInMemoryStoreType) ist ein temporärer Speicher im RAM ohne Festplattenpersistenz, der für Tests und Caching verwendet wird.

SpeichertypFormatLeistungVerwendungszweck
SQLite.sqliteHochStandardwahl für Produktion
Binary.binaryMittelKleine Datensätze
In-MemoryRAMMaximalTests, Cache, temporäre Daten
CloudKitiCloudNetzwerkabhängigGeräteübergreifende Synchronisation

Der Speichertyp wird mit einer einzigen Zeile bei der Initialisierung von NSPersistentStoreDescription festgelegt. Der Entwickler kann von SQLite auf In-Memory für Unit-Tests oder auf CloudKit für iCloud-Synchronisation umschalten, ohne den Objektmanipulationscode zu ändern — Core Data abstrahiert die Unterschiede zwischen Speichertypen durch eine einheitliche Kontext-API.

NSManagedObject und NSManagedObjectContext

NSManagedObject ist die Basisklasse für alle Core Data-Objekte und repräsentiert einen einzelnen Entitätsdatensatz. Jedes verwaltete Objekt hat eine eindeutige NSManagedObjectID (persistente Kennung), ist an einen Kontext gebunden und verfolgt seine Änderungen über KVO (Key-Value Observing). Entwickler erstellen NSManagedObject-Unterklassen, um typisierte Entitätseigenschaften zu definieren.

NSManagedObjectContext ist die zentrale Core Data-Komponente, die einen Arbeitsbereich für alle Objektoperationen bereitstellt. Der Kontext verfolgt Hinzufügungen, Löschungen und Änderungen (Change Tracking), unterstützt das Rückgängigmachen von Operationen über undoManager und führt beim Empfang von Speicherbenachrichtigungen automatisch Änderungen aus anderen Kontexten zusammen.

Thread-Sicherheit von Kontexten

Die Regel privater Warteschlangen: NSManagedObjectContext wird mit .privateQueueConcurrencyType oder .mainQueueConcurrencyType erstellt. Der Hauptkontext ist an den Haupt-UI-Thread gebunden, während private Kontexte auf Hintergrundwarteschlangen laufen. Jeder Kontext darf nur in seiner eigenen Warteschlange verwendet werden — der Zugriff auf ein verwaltetes Objekt von einem anderen Thread führt zu einem Absturz. parentContext ermöglicht die Organisation einer Hierarchie von Kontexten für asynchrone Schreibvorgänge.

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 erstellt automatisch viewContext (main queue) und stellt newBackgroundContext() für Hintergrundoperationen bereit. Die Einstellung automaticallyMergesChangesFromParent = true bewirkt, dass viewContext automatisch Änderungen aus Hintergrundkontexten übernimmt, wenn diese speichern, und die UI ohne manuelles erneutes Abrufen der Daten aktualisiert.

Persistenter Speicher und SQLite

NSPersistentStoreCoordinator verwaltet den physischen Datenspeicher: Er öffnet die Datei, erstellt SQLite-Tabellen basierend auf dem Modell und führt Migrationen bei Schemaänderungen durch. Bei der Initialisierung von NSPersistentStoreDescription mit NSSQLiteStoreType erstellt Core Data eine SQLite-Datei mit einem Schema, das dem .xcdatamodeld-Modell entspricht.

Core Data verwendet keine Standard-SQL-Abfragen über SELECT/INSERT/UPDATE. Stattdessen generiert es interne SQL-Befehle basierend auf dem Modell und Abfragen, die über NSFetchRequest durchgeführt werden. Der Entwickler kann die SQL-Protokollierung mit dem Startargument -com.apple.CoreData.SQLDebug 1 zur Abfrageleistungsdebugging aktivieren.

Core Data-Migrationen

Leichte Migration (Lightweight Migration) ist ein automatischer Prozess zur Aktualisierung des SQLite-Schemas beim Hinzufügen neuer Attribute, Ändern von optional/required-Flags oder Umbenennen mit renamingID. Schwere Migration ist bei grundlegenden Schemaänderungen wie dem Zusammenführen oder Aufteilen von Entitäten erforderlich und wird über einen benutzerdefinierten NSMigrationManager durchgeführt.

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)") }
}

Die Einrichtung der automatischen Migration über NSMigratePersistentStoresAutomaticallyOption und NSInferMappingModelAutomaticallyOption ermöglicht es Core Data, die SQLite-Datei beim Hinzufügen von Attributen oder Entitäten in einer neuen Modellversion unabhängig zu aktualisieren. Ist eine Migration nicht möglich, wirft der Store-Koordinator einen Fehler mit einer Beschreibung der Ursache — der Entwickler muss dann eine benutzerdefinierte Migration über NSMigrationManager implementieren.

Core Data in der Praxis: Code und Beispiele

NSFetchRequest ist das primäre Werkzeug zum Abrufen von Objekten aus Core Data. Eine Anfrage enthält den Entitätsnamen, ein Prädikat (Filter), Sortierbeschreibungen, Limit und Offset. Das Ergebnis wird als Array von NSManagedObject oder typisierten Unterklassen zurückgegeben. NSPredicate unterstützt komplexe Bedingungen mit AND, OR, IN, LIKE und Unterabfragen.

NSBatchDeleteRequest ist eine effiziente Möglichkeit, Objekte massenhaft zu löschen, ohne jedes einzelne in den Speicher zu laden. Die Anfrage wird auf SQLite-Ebene ausgeführt, umgeht den verwalteten Objektkontext und aktualisiert den Kontext erst nach Abschluss. Ähnliche Batch-Anfragen existieren zum Aktualisieren (NSBatchUpdateRequest) und Einfügen (NSBatchInsertRequest).

Beispiel für CRUD-Operationen

CRUD (Create, Read, Update, Delete) in Core Data wird über Kontextmethoden ausgeführt: insert, fetch, save und delete. Alle Änderungen sind temporär, bis context.save() aufgerufen wird — diese Methode speichert Änderungen im persistenten SQLite-Speicher. Bei einem Speicherfehler bleibt der Kontext für einen erneuten Versuch im geänderten Zustand.

swift
let context = container.viewContext

// Erstellen
let user = User(context: context)
user.id = 42
user.name = "Alice"

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

// Aktualisieren
results.first?.name = "Alice Updated"

// Löschen
if let first = results.first { context.delete(first) }

// Speichern
try context.save()

Das Speichern des Kontexts (context.save()) ist ein kritischer Vorgang. Wenn save nicht aufgerufen wird, bleiben alle Änderungen nur im Speicher. Der Kontext verfolgt den hasChanges-Status, der vor dem Speichern überprüft werden kann. Für Hintergrundoperationen verwenden Sie newBackgroundContext mit eigenem Speichern und für die UI viewContext mit automatischem Speichern per Timer oder beim Eintritt der App in den Hintergrund.

Core Data Best Practices

Erste Praxis — verwenden Sie NSPersistentCloudKitContainer zur Synchronisation von Daten zwischen Benutzergeräten über iCloud. Die Cloud-Synchronisation wird durch Hinzufügen der CloudKit-Option zur Persistent Store-Beschreibung aktiviert. Core Data verwaltet Synchronisationskonflikte automatisch und führt Änderungen von anderen Geräten zusammen.

Zweite Praxis — vermeiden Sie fetchRequest ohne Prädikat bei großen Tabellen. Jeder bedingungslose Fetch lädt alle Entitätsobjekte in den Speicher, was zu hohem RAM-Verbrauch und UI-Verlangsamung führt. Verwenden Sie immer Prädikate und Limits. Für Paginierung verwenden Sie fetchLimit und fetchOffset in NSFetchRequest.

Dritte Praxis — konfigurieren Sie mergePolicy zur Lösung von Konflikten beim Multithread-Zugriff. NSMergeByPropertyObjectTrumpMergePolicy aktualisiert konfliktierende Eigenschaften aus dem zuletzt gespeicherten Kontext. NSRollbackMergePolicy verwirft aktuelle Kontextänderungen bei Konflikten. Die Wahl der Richtlinie hängt von der Geschäftslogik der Anwendung ab.

Vierte Praxis — verwenden Sie NSFetchedResultsController für die Integration mit Tabellen und Sammlungen. Er abonniert automatisch NSManagedObjectContextDidSave-Benachrichtigungen, lädt nur erforderliche Objekte (Faulting) und benachrichtigt den Delegierten über Einfügungen, Löschungen und Verschiebungen mit entsprechenden Indexpfaden für UITableView-Animationen.

Leistung: Prefetching und Faulting

Faulting ist der Lazy-Loading-Mechanismus von Core Data. Ein von einer Fetch-Anfrage zurückgegebenes verwaltetes Objekt befindet sich im Fault-Zustand — seine Attribute sind nicht vollständig geladen, nur die Kennung. Das vollständige Laden (Fire Fault) erfolgt beim ersten Zugriff auf ein Attribut. Relationship Prefetching (setRelationshipKeyPathsForPrefetching) lädt verwandte Objekte im Voraus und vermeidet N+1-Abfragen.

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 veranlasst Core Data, Daten in Batches von 20 Objekten zu laden (zur Bildschirmanzeige), ohne die gesamte Tabelle auf einmal zu laden. Das Flag returnsObjectsAsFaults = false stellt sicher, dass alle Benutzerattribute sofort geladen werden, was für die direkte Anzeige nützlich ist. Das Prefetching der “posts”-Beziehung vermeidet separate Abfragen für jeden Benutzer beim Zugriff auf Beiträge.

Häufig gestellte Fragen

Ist Core Data eine Datenbank?

Nein, Core Data ist ein Framework zur Objektgraphenverwaltung. Es bietet eine API zum Arbeiten mit Objekten, Verfolgen von Änderungen und deren Persistierung. Die Datenbank unter der Haube von Core Data (standardmäßig SQLite) sollte nicht mit dem Framework selbst verwechselt werden. Core Data ist ein ORM, kein DBMS.

Kann Core Data ohne SQLite verwendet werden?

Ja, Core Data unterstützt drei Speichertypen: SQLite, Binary und In-Memory. Der Speichertyp wird über NSPersistentStoreDescription festgelegt. In-Memory-Speicher persistiert keine Daten auf der Festplatte und eignet sich für Unit-Tests. Binary-Speicher ist ein Legacy-Format für kompakte Objektsätze.

Wie migriere ich Core Data auf eine neue Modellversion?

Für die leichte Migration aktivieren Sie NSMigratePersistentStoresAutomaticallyOption und NSInferMappingModelAutomaticallyOption. Für komplexe Änderungen erstellen Sie ein Mapping Model (.xcmappingmodel) über Xcode. CloudKit-Speicher (NSPersistentCloudKitContainer) unterstützt Migrationen automatisch beim Synchronisieren des Schemas mit dem iCloud-Server.

Wie unterscheidet sich Core Data von SwiftData?

SwiftData ist ein neues Apple-Framework (iOS 17+), das auf Core Data aufbaut und Swift Macros und Swift Concurrency verwendet. SwiftData hat eine einfachere Syntax: Entitäten werden mit dem @Model-Makro beschrieben, Kontext mit @Environment(\.modelContext). Unter der Haube verwendet SwiftData denselben Core Data-Stack und SQLite.

Wie debugge ich langsame Core Data-Abfragen?

Aktivieren Sie das Startargument -com.apple.CoreData.SQLDebug 1 — Core Data gibt alle SQL-Abfragen und deren Dauer in der Xcode-Konsole aus. Zur Profilerstellung verwenden Sie Instruments mit der Core Data-Vorlage, die die Anzahl der Fault-Anfragen, Objektladezeiten und Kontextspeicherdauer anzeigt.

Zusammenfassung

  • Core Data ist ein Framework zur Objektgraphenverwaltung und Persistenz für iOS und macOS, das SQLite als Standardspeicher verwendet.
  • Der Core Data-Stack umfasst NSManagedObjectModel, NSPersistentStoreCoordinator, NSManagedObjectContext und NSPersistentContainer für eine einheitliche Konfiguration.
  • NSManagedObjectContext ist ein Arbeitsbereich mit Änderungsverfolgung, Rückgängig-Unterstützung und automatischer Zusammenführung aus Hintergrundkontexten.
  • NSFetchRequest mit NSPredicate und Relationship-Prefetching ist das primäre Abrufwerkzeug, optimiert durch Batch-Größe und Faulting.
  • Lightweight Migration aktualisiert automatisch das SQLite-Schema beim Hinzufügen von Attributen und Entitäten in einer neuen Modellversion.
  • NSPersistentCloudKitContainer fügt iCloud-Synchronisation zwischen Benutzergeräten mit automatischer Konfliktlösung hinzu.
  • Empfehlung — verwenden Sie Core Data für iOS-Anwendungen mit hierarchischen Objektmodellen; für einfache lokale Speicherung ziehen Sie GRDB oder SwiftData in Betracht.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch