수색…


비고

이것은 프로젝트가 생성 될 때 핵심 데이터로 프로젝트가 생성되는 경우 AppDelegate 파일에 처음으로 배치되는 핵심 데이터 스택의 구현입니다. 이 함수는 CoreDataStack.swift 대해 별도의 클래스로 구현 될 수도 있습니다. 주요 기능 중 하나는 NSManagedObjectContext를 가져 오는 것입니다.

목표 -C

- (NSManagedObjectContext *)managedObjectContext {...}

스위프트 2

lazy var managedObjectContext: NSManagedObjectContext = {...}

스위프트 3

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

응용 프로그램의 개체와 외부 데이터 저장소간에 통신하는 핵심 데이터 스택입니다. 핵심 데이터 스택은 응용 프로그램이 비즈니스 논리에 집중할 수 있도록 외부 데이터 저장소와의 모든 상호 작용을 처리합니다. 스택은 관리 대상 객체 컨텍스트 ( NSManagedObjectContext ), 영구 저장소 조정자 ( NSPersistentStoreCoordinator ) 및 관리 객체 모델 ( NSManagedObjectModel )의 세 가지 기본 객체로 구성됩니다.

NSManagedObjectModel

NSManagedObjectModel 인스턴스는 코어 데이터 스택에 의해 액세스 될 데이터를 설명합니다. NSManagedObjectModel (종종 "엄마"라고 함)은 스택 생성의 첫 번째 단계로 메모리에로드됩니다. NSManagedObjectModel 의 예는 DataModel.momd입니다. NSManagedObjectModel 은 데이터의 구조를 정의합니다.

NSPersistentStoreCoordinator

NSPersistentStoreCoordinator 는 영구 저장소의 데이터에서 개체를 인식하고 해당 개체를 요청한 NSManagedObjectContext 합니다. 모델에서 엔티티의 새 인스턴스를 만들고 영구 저장소 ( NSPersistentStore )에서 기존 인스턴스를 검색합니다. NSPersistentStoreCoordinator 는 또한 데이터가 NSManagedObjectModel 의 정의와 일치하는 일관성있는 상태에 있는지 확인합니다.

NSManagedObjectContext

영구 저장소에서 오브젝트를 가져올 때 임시 사본을 오브젝트 그래프 (또는 오브젝트 그래프의 콜렉션)를 형성하는 스크래치 패드로 가져옵니다. 그런 다음 해당 변경 사항을 실제로 저장하지 않으면 해당 오브젝트를 수정할 수 있지만 영구 저장소는 변경되지 않습니다.

모든 관리 객체는 관리 객체 컨텍스트로 등록되어야합니다. 컨텍스트를 사용하여 개체 그래프에 개체를 추가하고 개체 그래프에서 개체를 제거합니다. 컨텍스트는 개별 개체의 특성과 개체 간의 관계에 대한 변경 내용을 추적합니다. 변경 내용을 추적하여 컨텍스트에서 실행 취소 및 다시 실행 지원을 제공 할 수 있습니다. 또한 오브젝트 간의 관계를 변경하면 오브젝트 그래프의 + 결성이 유지됩니다.

변경 사항을 저장할 때 컨텍스트는 개체가 유효한 상태인지 확인합니다. 변경 사항은 영구 저장소 (또는 저장소)에 기록되고 사용자가 만든 개체에 대한 새 레코드가 추가되며 삭제 한 개체에 대한 레코드는 제거됩니다.

출처 : Apple Core Data Programming : 핵심 데이터 스택 초기화

목표 -C 예제

이것은 iOS 10 이상의 단순하지만 강력한 코어 데이터 설정입니다. 핵심 데이터에 액세스하는 방법은 두 가지가 있습니다.

  1. viewContext . viewContext 는 주 스레드에서만 사용할 수 있으며 읽기 전용입니다.
  2. 강력한 enqueueCoreDataBlock . 모든 쓰기는 enqueueCoreDataBlock 사용하여 수행해야합니다. 마지막으로 저장하지 않아도 자동으로 저장됩니다. 모든 쓰기는 operationQueue에 대기열에 포함되므로 쓰기 충돌이 발생할 수 없습니다.

다른 컨텍스트의 컨텍스트에서 managedObject를 절대 사용하지 마십시오. 또한 enqueueCoreDataBlock 에서 생성되거나 페치 된 모든 객체를 폐기합니다. 객체를 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;
}

신속한 예 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()
        }
    }
}

Swift에서의 iOS 10 예제

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