Buscar..


Observaciones

Esta es una implementación de la pila de datos principales que se coloca inicialmente en el archivo AppDelegate si el proyecto se crea con los datos principales cuando se crea el proyecto. Estas funciones también pueden implementarse en clases separadas para CoreDataStack.swift . Una de las funciones principales es obtener NSManagedObjectContext.

C objetivo

- (NSManagedObjectContext *)managedObjectContext {...}

Swift 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

Swift 3

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

La pila de datos principales que se comunica entre los objetos en su aplicación y los almacenes de datos externos. La pila Core Data maneja todas las interacciones con los almacenes de datos externos para que su aplicación pueda centrarse en su lógica de negocios. La pila consta de tres objetos primarios: el contexto del objeto administrado ( NSManagedObjectContext ), el coordinador de tienda persistente ( NSPersistentStoreCoordinator ) y el modelo de objeto administrado ( NSManagedObjectModel ).

NSManagedObjectModel

La instancia de NSManagedObjectModel describe los datos a los que la pila Core Data accederá. NSManagedObjectModel (a menudo denominado "mamá") se carga en la memoria como el primer paso en la creación de la pila. Un ejemplo de NSManagedObjectModel es DataModel.momd. El NSManagedObjectModel define la estructura de los datos

NSPersistentStoreCoordinator

El NSPersistentStoreCoordinator realiza los objetos de los datos en el almacén persistente y pasa esos objetos al NSManagedObjectContext solicitante. Crea nuevas instancias de las entidades en el modelo y recupera instancias existentes de un almacén persistente ( NSPersistentStore ). El NSPersistentStoreCoordinator también verifica que los datos se encuentren en un estado coherente que coincida con las definiciones en NSManagedObjectModel .

NSManagedObjectContext

Cuando recuperas objetos de un almacén persistente, traes copias temporales al bloc de notas donde forman un gráfico de objetos (o una colección de gráficos de objetos). Luego puede modificar esos objetos, a menos que realmente guarde esos cambios, sin embargo, el almacén persistente permanece inalterado.

Todos los objetos gestionados deben registrarse con un contexto de objeto gestionado. Utiliza el contexto para agregar objetos al gráfico de objetos y eliminar objetos del gráfico de objetos. El contexto rastrea los cambios que realiza, tanto a los atributos de los objetos individuales como a las relaciones entre los objetos. Al realizar un seguimiento de los cambios, el contexto puede proporcionarle ayuda para deshacer y rehacer. También garantiza que si cambia las relaciones entre los objetos, se mantiene la integridad del gráfico de objetos.

Cuando guarda los cambios, el contexto garantiza que sus objetos se encuentren en un estado válido. Los cambios se escriben en el almacén (o almacenes) persistentes, se agregan nuevos registros para los objetos que creó y los registros se eliminan para los objetos que eliminó.

Fuente: Apple Core Data Programming: Inicializando la pila de datos Core

Objective-C Ejemplo

Esta es una configuración simple pero robusta de datos básicos para iOS 10+. Hay exactamente dos formas de acceder a los datos principales:

  1. viewContext . El viewContext solo se puede usar desde el hilo principal, y solo para leer.
  2. EnqueueCoreDataBlock fuerte . Toda la escritura debe hacerse utilizando enqueueCoreDataBlock . No hay necesidad de guardar al final, se guardará automáticamente. Todas las escrituras se ponen en cola en una OperationQueue para que nunca haya conflictos de escritura.

Asegúrese de que NUNCA use ningún objeto gestionado del contexto en otro contexto. También descarte todos los objetos que se crean o se recuperan en enqueueCoreDataBlock ya que el contexto que los respalda se destruirá después de que se ejecute el bloque.

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

// 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()
        }
    }
}

Ejemplo de iOS 10 en 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow