Sök…


Anmärkningar

Detta är en implementering av Core Data Stack som initialt placeras i AppDelegate filen om projektet skapas med Core Data när projekt skapas. Dessa funktioner kan också implementeras i separat klass för CoreDataStack.swift . En av de viktigaste funktionerna är att få NSManagedObjectContext.

Objective-C

- (NSManagedObjectContext *)managedObjectContext {...}

Snabb 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

Snabb 3

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

Core Data-stacken som kommunicerar mellan objekten i din applikation och externa datalagrar. Core Data-stacken hanterar alla interaktioner med de externa datalagren så att din applikation kan fokusera på dess affärslogik. Bunten består av tre primära objekt: det hanterade objektets sammanhang ( NSManagedObjectContext ), den persistenta butikskoordinatorn ( NSPersistentStoreCoordinator ) och den hanterade objektmodellen ( NSManagedObjectModel ).

NSManagedObjectModel

NSManagedObjectModel beskriver de data som kommer att nås av Core Data-stacken. NSManagedObjectModel (ofta kallad ”mamma”) laddas i minnet som det första steget i skapandet av stacken. Ett exempel på NSManagedObjectModel är DataModel.momd. NSManagedObjectModel definierar strukturen för data

NSPersistentStoreCoordinator

NSPersistentStoreCoordinator inser objekt från data i den ihållande lagringen och skickar dessa objekt till den begärande NSManagedObjectContext . Det skapar nya instanser av enheterna i modellen och hämtar befintliga instanser från en ihållande butik ( NSPersistentStore ). NSPersistentStoreCoordinator verifierar också att uppgifterna är i ett konsekvent tillstånd som matchar definitionerna i NSManagedObjectModel .

NSManagedObjectContext

När du hämtar objekt från en ihållande butik tar du med tillfälliga kopior på skrapplattan där de bildar ett objektdiagram (eller en samling av objektgrafer). Du kan sedan ändra dessa objekt, såvida du inte sparar ändringarna, men den bestående butiken förblir oförändrad.

Alla hanterade objekt måste registreras med ett hanterat objektssammanhang. Du använder sammanhanget för att lägga till objekt i objektgrafen och ta bort objekt från objektgrafen. Kontexten spårar de ändringar du gör, både till enskilda objekts attribut och till förhållandena mellan objekt. Genom att spåra förändringar kan kontexten ge ångra och göra om support för dig. Det säkerställer också att om du ändrar förhållanden mellan objekt, hålls objekts grafens integritet.

När du sparar ändringar säkerställer sammanhanget att dina objekt är i giltigt tillstånd. Ändringarna skrivs till den bestående butiken (eller butikerna), nya poster läggs till för objekt du skapade och poster tas bort för objekt som du har tagit bort.

Källa: Apple Core Data Programming: Initiera Core Data Stack

Objekt-C-exempel

Detta är en enkel men robust inställning av kärndata för iOS 10+. Det finns exakt två sätt att få tillgång till kärndata:

  1. viewContext . viewContext kan endast användas från huvudtråden och endast för läsning.
  2. stark enqueueCoreDataBlock . All skrivning ska göras med enqueueCoreDataBlock . Det finns inget behov av att spara i slutet kommer det automatiskt att spara. Alla skrivningar är förknippade i en operationQueue så det kan aldrig finnas skrivkonflikter.

Se till att ALDRIG använda förvaltade objekt från sammanhang i ett annat sammanhang. Kassera också alla objekt som skapas eller hämtas i enqueueCoreDataBlock eftersom det sammanhang som stöder dem kommer att förstöras efter att blocket har körts.

// 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;
}

Exempel på Swift 2

// 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-exempel i 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow