Ricerca…


Osservazioni

Questa è un'implementazione del Core Data Stack che viene inizialmente inserito nel file AppDelegate se il progetto viene creato con Core Data al momento della creazione del progetto. Queste funzioni possono anche essere implementate in una classe separata per CoreDataStack.swift . Una delle funzioni principali è ottenere NSManagedObjectContext.

Objective-C

- (NSManagedObjectContext *)managedObjectContext {...}

Swift 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

Swift 3

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

Lo stack di dati principali che comunica tra gli oggetti nell'applicazione e gli archivi di dati esterni. Lo stack di Core Data gestisce tutte le interazioni con gli archivi di dati esterni in modo che l'applicazione possa concentrarsi sulla sua logica di business. Lo stack è costituito da tre oggetti primari: il contesto dell'oggetto gestito ( NSManagedObjectContext ), il coordinatore NSPersistentStoreCoordinator permanente ( NSPersistentStoreCoordinator ) e il modello oggetto gestito ( NSManagedObjectModel ).

NSManagedObjectModel

L'istanza di NSManagedObjectModel descrive i dati a cui sarà possibile accedere dallo stack dei Core Data. NSManagedObjectModel (spesso chiamato "mamma") viene caricato in memoria come primo passo nella creazione dello stack. Un esempio di NSManagedObjectModel è DataModel.momd. Il NSManagedObjectModel definisce la struttura dei dati

NSPersistentStoreCoordinator

NSPersistentStoreCoordinator realizza oggetti dai dati nell'archivio permanente e li inoltra al NSManagedObjectContext richiedente. Crea nuove istanze delle entità nel modello e recupera le istanze esistenti da un archivio persistente ( NSPersistentStore ). NSPersistentStoreCoordinator verifica inoltre che i dati siano in uno stato coerente che corrisponde alle definizioni in NSManagedObjectModel .

NSManagedObjectContext

Quando recuperi oggetti da un archivio persistente, porti delle copie temporanee sul blocco da disegno dove formano un oggetto grafico (o una raccolta di grafici di oggetti). È quindi possibile modificare tali oggetti, a meno che non si salvino effettivamente tali modifiche, tuttavia, l'archivio permanente rimane inalterato.

Tutti gli oggetti gestiti devono essere registrati con un contesto dell'oggetto gestito. Si utilizza il contesto per aggiungere oggetti al grafico dell'oggetto e rimuovere oggetti dal grafico dell'oggetto. Il contesto tiene traccia delle modifiche apportate, sia agli attributi degli oggetti individuali sia alle relazioni tra gli oggetti. Tracciando le modifiche, il contesto è in grado di fornire supporto di annullamento e ripetizione per te. Garantisce inoltre che se si modificano le relazioni tra gli oggetti, viene mantenuta l'integrità del grafico dell'oggetto.

Quando salvi le modifiche, il contesto garantisce che gli oggetti siano in uno stato valido. Le modifiche vengono scritte nell'archivio permanente (o nei negozi), vengono aggiunti nuovi record per gli oggetti creati e i record vengono rimossi per gli oggetti eliminati.

Fonte: Apple Core Data Programming: inizializzazione dello stack dei dati principali

Esempio-C Esempio

Questa è una semplice ma robusta configurazione dei dati di base per iOS 10+. Ci sono esattamente due modi per accedere ai dati principali:

  1. viewContext . viewContext può essere utilizzato solo dal thread principale e solo per la lettura.
  2. strong enqueueCoreDataBlock . Tutta la scrittura dovrebbe essere fatta usando enqueueCoreDataBlock . Non è necessario salvare alla fine si salverà automaticamente. Tutte le scritture vengono accodate in un'operazioneQueue, quindi non ci possono essere conflitti di scrittura.

Assicurati di NON utilizzare MAI oggetti gestiti dal contesto in un altro contesto. Inoltre, elimina tutti gli oggetti che sono stati creati o recuperati in enqueueCoreDataBlock poiché il contesto che li supporta verrà distrutto dopo l'esecuzione del blocco.

// 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 Esempio

// 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 Esempio 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow