Suche…


Bemerkungen

Dies ist eine Implementierung des Core Data Stack, die anfänglich in der AppDelegate Datei AppDelegate wird, wenn das Projekt beim AppDelegate des Projekts mit Core Data erstellt wird. Diese Funktionen können auch in einer separaten Klasse für CoreDataStack.swift . Eine der wichtigsten Funktionen ist das Abrufen des NSManagedObjectContext.

Ziel c

- (NSManagedObjectContext *)managedObjectContext {...}

Schnell 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

Swift 3

lazy var persistentContainer: NSPersistentContainer = {...)
let managedObjectContext = persistentContainer.viewContext

Der Core Data Stack, der zwischen den Objekten in Ihrer Anwendung und externen Datenspeichern kommuniziert. Der Core-Data-Stack übernimmt alle Interaktionen mit den externen Datenspeichern, sodass sich Ihre Anwendung auf ihre Geschäftslogik konzentrieren kann. Der Stapel besteht aus drei primären Objekten: dem Kontext für verwaltete Objekte ( NSManagedObjectContext ), dem Koordinator für persistenten Speicher ( NSPersistentStoreCoordinator ) und dem Modell für verwaltete Objekte ( NSManagedObjectModel ).

NSManagedObjectModel

Die NSManagedObjectModel Instanz beschreibt die Daten, auf die der Core Data-Stack NSManagedObjectModel soll. NSManagedObjectModel (oft als "Mom" bezeichnet) wird als erster Schritt bei der Erstellung des Stacks in den Speicher geladen. Ein Beispiel für das NSManagedObjectModel ist DataModel.momd. Das NSManagedObjectModel definiert die Struktur der Daten

NSPersistentStoreCoordinator

Der NSPersistentStoreCoordinator realisiert Objekte aus den Daten im permanenten Speicher und übergibt diese an den anfordernden NSManagedObjectContext . Es erstellt neue Instanzen der Entitäten im Modell und ruft vorhandene Instanzen aus einem permanenten Speicher ab ( NSPersistentStore ). Der NSPersistentStoreCoordinator überprüft auch, ob sich die Daten in einem konsistenten Zustand befinden, der den Definitionen im NSManagedObjectModel .

NSManagedObjectContext

Wenn Sie Objekte aus einem permanenten Speicher abrufen, bringen Sie temporäre Kopien auf den Notizblock, wo sie ein Objektdiagramm (oder eine Sammlung von Objektdiagrammen) bilden. Sie können diese Objekte dann ändern, sofern Sie diese Änderungen nicht wirklich speichern. Der persistente Speicher bleibt jedoch unverändert.

Alle verwalteten Objekte müssen mit einem verwalteten Objektkontext registriert werden. Sie verwenden den Kontext, um Objekte zum Objektdiagramm hinzuzufügen und Objekte aus dem Objektdiagramm zu entfernen. Der Kontext verfolgt die Änderungen, die Sie vornehmen, sowohl an den Attributen einzelner Objekte als auch an den Beziehungen zwischen Objekten. Durch das Nachverfolgen von Änderungen kann der Kontext Sie rückgängig machen und wiederholen. Dadurch wird auch sichergestellt, dass beim Ändern von Beziehungen zwischen Objekten die Integrität des Objektdiagramms erhalten bleibt.

Wenn Sie Änderungen speichern, stellt der Kontext sicher, dass sich Ihre Objekte in einem gültigen Status befinden. Die Änderungen werden in den permanenten Speicher (oder in die Speicher) geschrieben, neue Datensätze werden für von Ihnen erstellte Objekte hinzugefügt und Datensätze für gelöschte Objekte werden entfernt.

Quelle: Apple Core Data Programming: Initialisieren des Core Data Stack

Ziel-C-Beispiel

Dies ist ein einfaches, aber robustes Core-Data-Setup für iOS 10+. Es gibt genau zwei Möglichkeiten, auf Kerndaten zuzugreifen:

  1. viewContext . Der viewContext kann nur vom Haupt-Thread und nur zum Lesen verwendet werden.
  2. starker enqueueCoreDataBlock . Alles Schreiben sollte mit enqueueCoreDataBlock . Es ist nicht notwendig, am Ende zu speichern, es wird automatisch gespeichert. Alle Schreibvorgänge werden in einer operationQueue in eine Warteschlange gestellt, sodass es nie zu Schreibkonflikten kommen kann.

Stellen Sie sicher, dass Sie NIEMALS verwalteteObjekte aus dem Kontext in einem anderen Kontext verwenden. enqueueCoreDataBlock auch alle Objekte, die in enqueueCoreDataBlock als Kontext erstellt oder abgerufen werden, der sie unterstützt, nachdem der Block ausgeführt wird.

// CoreDataManager.h

@interface CoreDataManager : NSObject
@property (nonatomic, readonly) NSManagedObjectContext * viewContext;
- (void)enqueueCoreDataBlock:(void (^)(NSManagedObjectContext* context))block;
@end

// CoreDataManager.m

@implementation NSManagedObjectContext(SaveIfNeeded)
-(BOOL) saveIfNeeded{
    BOOL toReturn = YES;
    if ([self hasChanges]) {
        NSError *error;
        toReturn = [self save:&error];
        if (toReturn == NO || error)
        {
            //Here you should log to your analytics service
            NSLog(@"--- Failed to commit data\n error: %@", error);
        }
    }
    return toReturn;
}
@end
@interface CoreDataManager ()
@property (nonatomic, strong) NSPersistentContainer* persistentContainer;
@property (nonatomic, strong) NSOperationQueue* persistentContainerQueue;    
@end
@implementation CoreDataManager

- (id)init
{
    self = [super init]
    if (self)
    {
        self.persistentContainer = [[NSPersistentContainer alloc] initWithName:@"PROJECT_NAME_ALSO_NAME_OF_MODEL" managedObjectModel:managedObjectModel];
        [self.persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription * description, NSError * error) {              
        }];
        self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
        _persistentContainerQueue = [[NSOperationQueue alloc] init];
        _persistentContainerQueue.maxConcurrentOperationCount = 1;
        _persistentContainerQueue.name = @"persistentContainerQueue";
        dispatch_queue_t queue = dispatch_queue_create("persistentContainerQueue.dispatchQueue", DISPATCH_QUEUE_SERIAL);
        _persistentContainerQueue.underlyingQueue = queue;            
    }
}

- (void)enqueueCoreDataBlock:(void (^)(NSManagedObjectContext* context))block{
    void (^blockCopy)(NSManagedObjectContext*) = [block copy];

    [self.persistentContainerQueue addOperation:[NSBlockOperation blockOperationWithBlock:^{
        NSManagedObjectContext* context =  self.persistentContainer.newBackgroundContext;
        [context performBlockAndWait:^{
            blockCopy(context);
            [context saveIfNeeded];
        }];
    }]];
}

-(NSManagedObjectContext*) viewContext{
    if (![NSThread mainThread]) {
        //here you should log to you analytics service. If you are in developer mode you should crash to force you to fix this
        NSLog(@"access context on wrong thread!!");
    }
    return self.persistentContainer.viewContext;
}

Swift 2 Beispiel

// Core Data stack

lazy var applicationDocumentsDirectory: NSURL = {
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.count-1]
}()

lazy var managedObjectModel: NSManagedObjectModel = {
    let modelURL = NSBundle.mainBundle().URLForResource("ProjectName", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {

    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
    } catch {
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        print("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
    
    return coordinator
}()

lazy var managedObjectContext: NSManagedObjectContext = {
    let coordinator = self.persistentStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()

// Core Data Saving support

func saveContext () {
    if managedObjectContext.hasChanges {
        do {
            try managedObjectContext.save()
        } catch {
            let nserror = error as NSError
            print("Unresolved error \(nserror), \(nserror.userInfo)")
            abort()
        }
    }
}

iOS 10 Beispiel in Swift

lazy var persistentContainer: NSPersistentContainer = {
    
    let container = NSPersistentContainer(name: "ProjectName")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        
        if let error = error {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
    
func saveContext () {
    let context = persistentContainer.viewContext
    
    do {
        try context.save()
    } catch {
        let nserror = error as NSError
        fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
    }
    
    if context.hasChanges {
        print("changes occured")
    }else {
        print("no changes occured")
    }
    
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow