サーチ…


備考

これは、プロジェクトが作成されたときにコアデータを使用してプロジェクトが作成された場合、最初にAppDelegateファイルに配置されるコアデータスタックの実装です。これらの関数はCoreDataStack.swift別のクラスで実装することもできます。主な機能の1つは、NSManagedObjectContextを取得することです。

目標-C

- (NSManagedObjectContext *)managedObjectContext {...}

スウィフト2

lazy var managedObjectContext: NSManagedObjectContext = {...}

スウィフト3

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

アプリケーション内のオブジェクトと外部データストア間で通信するコアデータスタック。コアデータスタックは、アプリケーションがビジネスロジックに集中できるように、外部データストアとのすべての対話を処理します。スタックは、管理対象オブジェクトコンテキスト( NSManagedObjectContext )、永続ストアコーディネータ( NSPersistentStoreCoordinator )、および管理対象オブジェクトモデル( NSManagedObjectModel )の3つの主要オブジェクトから構成されます。

NSManagedObjectModel

NSManagedObjectModelインスタンスは、コアデータスタックによってアクセスされるデータを記述します。 NSManagedObjectModel (しばしば「ママ」と呼ばれる)は、スタックの作成の最初のステップとしてメモリにロードされます。 NSManagedObjectModelの例は、DataModel.momdです。 NSManagedObjectModelは、データの構造を定義します

NSPersistentStoreCoordinator

NSPersistentStoreCoordinatorは、永続ストア内のデータからオブジェクトを認識し、そのオブジェクトを要求元のNSManagedObjectContextます。モデル内のエンティティの新しいインスタンスを作成し、既存のインスタンスを永続ストア( NSPersistentStore )から取得します。 NSPersistentStoreCoordinatorは、データがNSManagedObjectModel定義と一致する一貫した状態にあることも確認します。

NSManagedObjectContext

永続ストアからオブジェクトをフェッチするときは、テンポラリ・コピーをスクラッチ・パッドに持ってきて、オブジェクト・グラフ(またはオブジェクト・グラフの集合)を形成します。実際に変更を保存しないかぎり、これらのオブジェクトを変更できますが、永続ストアは変更されません。

すべての管理対象オブジェクトは、管理対象オブジェクトコンテキストに登録する必要があります。コンテキストを使用してオブジェクトグラフにオブジェクトを追加し、オブジェクトグラフからオブジェクトを削除します。コンテキストは、個々のオブジェクトの属性とオブジェクト間の関係の両方に加えた変更を追跡します。変更を追跡することによって、コンテキストは元に戻すとやり直しのサポートを提供することができます。また、オブジェクト間の関係を変更すると、オブジェクトグラフの整合性が維持されます。

変更を保存すると、コンテキストによってオブジェクトが有効な状態になります。変更は永続ストア(またはストア)に書き込まれ、作成したオブジェクトの新しいレコードが追加され、削除したオブジェクトのレコードは削除されます。

出典: Apple Core Data Programming:コアデータスタックの初期化

目的-Cの例

これは、iOS 10以降のシンプルで堅牢なコアデータ設定です。コアデータにアクセスするには、2通りの方法があります。

  1. viewContextviewContextは、メインスレッドからのviewContext専用に使用できます。
  2. 強いenqueueCoreDataBlock 。すべての書き込みは、 enqueueCoreDataBlockを使用して行う必要があります。最後に保存する必要はありませんが、自動的に保存されます。すべての書き込みはoperationQueueにエンキューされ、書き込み競合が発生することはありません。

別のコンテキストのコンテキストからmanagedObjectsを絶対に使用しないでください。 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