Поиск…


замечания

Это реализация основного стека данных, который изначально помещается в файл AppDelegate если проект создается с помощью Core Data при создании проекта. Эти функции также могут быть реализованы в отдельном классе для CoreDataStack.swift . Одной из основных функций является получение NSManagedObjectContext.

Objective-C

- (NSManagedObjectContext *)managedObjectContext {...}

Swift 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

Swift 3

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

Стек Core Data, который взаимодействует между объектами вашего приложения и внешними хранилищами данных. Стек Core Data обрабатывает все взаимодействия с внешними хранилищами данных, чтобы ваше приложение могло сосредоточиться на своей бизнес-логике. Стек состоит из трех основных объектов: контекста управляемого объекта ( NSManagedObjectContext ), постоянного координатора хранилища ( NSPersistentStoreCoordinator ) и модели управляемых объектов ( NSManagedObjectModel ).

NSManagedObjectModel

Экземпляр NSManagedObjectModel описывает данные, к которым будет обращаться стек Core Data. NSManagedObjectModel (часто называемый «мама») загружается в память в качестве первого шага при создании стека. Примером NSManagedObjectModel является DataModel.momd. NSManagedObjectModel определяет структуру данных

NSPersistentStoreCoordinator

NSPersistentStoreCoordinator реализует объекты из данных в постоянном хранилище и передает эти объекты в запрашивающий NSManagedObjectContext . Он создает новые экземпляры объектов в модели и извлекает существующие экземпляры из постоянного хранилища ( NSPersistentStore ). NSPersistentStoreCoordinator также проверяет, что данные находятся в согласованном состоянии, которое соответствует определениям в NSManagedObjectModel .

NSManagedObjectContext

Когда вы извлекаете объекты из постоянного хранилища, вы привозите временные копии на блокнот, где они образуют граф объектов (или набор графиков объектов). Затем вы можете изменить эти объекты, если вы фактически не сохраните эти изменения, однако постоянное хранилище остается неизменным.

Все управляемые объекты должны быть зарегистрированы в контексте управляемого объекта. Вы используете контекст для добавления объектов в граф объектов и удаления объектов из графа объектов. Контекст отслеживает сделанные вами изменения как с атрибутами отдельных объектов, так и с отношениями между объектами. Отслеживая изменения, контекст может предоставить вам отмену и повторную поддержку. Он также гарантирует, что при изменении отношений между объектами сохраняется целостность графика объекта.

При сохранении изменений контекст гарантирует, что ваши объекты находятся в допустимом состоянии. Изменения записываются в постоянное хранилище (или хранилища), новые записи добавляются для созданных вами объектов и удаляются записи для удаленных объектов.

Источник: Apple Core Data Programming: Инициализация основного стека данных

Пример Objective-C

Это простая, но надежная настройка данных ядра для iOS 10+. Существует два способа доступа к основным данным:

  1. viewContext . viewContext может использоваться только из основного потока и только для чтения.
  2. strong enqueueCoreDataBlock . Все записи должны выполняться с помощью enqueueCoreDataBlock . Нет необходимости сохранять в конце, он автоматически сохранит. Все записи выводятся в очередь в операцииQueue, поэтому конфликты записи никогда не могут быть.

Обязательно никогда не используйте любые управляемые объекты из контекста в другом контексте. Также отмените все объекты, созданные или извлеченные в enqueueCoreDataBlock поскольку контекст, который их поддерживает, будет уничтожен после выполнения блока.

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

// 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 в 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow