web-dev-qa-db-ja.com

CoreData 'このNSPersistentStoreCoordinatorには永続的なストアがありません。保存操作を実行できません。」

ICloudサポートをCoreDataと統合するのに役立つ these の手順に従っていますが、エラーが発生します。

これは私のAppDelegateにあります:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    //NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Little_Wedding_Book_Universal.sqlite"];
    NSString *storePath = [[NSString stringWithFormat:@"%@", [self applicationDocumentsDirectory]] stringByAppendingPathComponent:@"appname.sqlite"];
    NSURL *storeURL = [NSURL fileURLWithPath:storePath];

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSPersistentStoreCoordinator* psc = persistentStoreCoordinator;

    if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0"))
    {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSFileManager *fileManager = [NSFileManager defaultManager];

            // Migrate datamodel
            NSDictionary *options = nil;

            // this needs to match the entitlements and provisioning profile
            NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:@"J9VXW4WCE8.com.company.appname"];
            NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"data"];
            if ([coreDataCloudContent length] != 0) {
                // iCloud is available
                cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];

                options = [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                           [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                           @"appname.store", NSPersistentStoreUbiquitousContentNameKey,
                           cloudURL, NSPersistentStoreUbiquitousContentURLKey,
                           nil];
            }
            else
            {
                // iCloud is not available
                options = [NSDictionary dictionaryWithObjectsAndKeys:
                           [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                           [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                           nil];
            }

            NSError *error = nil;
            [psc lock];
            if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
            {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }
            [psc unlock];

            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"asynchronously added persistent store!");
                [[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil];
            });

        });

    }
    else
    {
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                 nil];

        NSError *error = nil;
        if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }

    return persistentStoreCoordinator;
}

別のビューコントローラーで、AppDelegateのインスタンスを作成し、オブジェクトを作成して[appDelegate saveContext];を呼び出します。ここでアプリがクラッシュします。これは常に完全に機能してきました(これまでは、iCloudサポートを追加しています)。

-(void)saveContext
{
    NSError *error;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        }
    }
}

したがって、このメソッドでクラッシュし、コンソールに次のメッセージが表示されます。

'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores.  It cannot perform a save operation.'

私は何をすべきかわからない、助けて!

編集:以下のコンソールログ:

アプリを起動すると、次のようになります。

2012-08-22 17:39:47.906 appname[24351:707] asynchronously added persistent store!
2012-08-22 17:39:47.955 appname[24351:707] asynchronously added persistent store!

アプリがクラッシュした場合のフォローアップ:

2012-08-22 17:41:31.657 appname[24351:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores.  It cannot perform a save operation.'
*** First throw call stack:
(0x3749d88f 0x351a2259 0x36bf0fe7 0x36c59287 0xd648b 0x149e0b 0x373f73fd 0x3118ce07 0x3118cdc3 0x3118cda1 0x3118cb11 0x3118d449 0x3118b92b 0x3118b319 0x31171695 0x31170f3b 0x33bb322b 0x37471523 0x374714c5 0x37470313 0x373f34a5 0x373f336d 0x33bb2439 0x3119fcd5 0xd53dd 0xd5378)
terminate called throwing an exception(lldb) 
21
Josh Kahane

おそらく、2つ(またはそれ以上)の異なるスレッドからpersistentStoreCoordinatorメソッドを呼び出しています。直接的または間接的に。

書かれているように、そのメソッドはスレッドセーフではありません。

同じ問題を持つ他の方法がある可能性があります。通常、managedObjectContextが存在し、同様の方法で記述されます。

この問題を解決するには2つの方法があります。

  • 使用する @synchronizeこれらのメソッドをスレッドセーフにする
  • 初期化コードをそれらからinitメソッドに移動し、ivarがnilであるかどうかをアサート/除外するように変更します。

2番目に間違っているのは、ストアを初期化する前に、コンテキストを変更し(たとえば、新しい管理対象オブジェクトを追加するなど)、保存しようとすることです。

これを解決するには、次のいずれかを実行してください。

  • 少なくとも1つの管理対象オブジェクトが既に含まれている(ストアが読み込まれている)ことがわかっている場合を除き、管理対象オブジェクトをコンテキストに追加しません。
  • 既に存在することを確認せずにコンテキストに管理オブジェクトを追加する必要がある場合(たとえば、最初に空のストアを作成した後)、ストアがすでに初期化されていることを確認してください(たとえば、RefetchAllDatabaseData通知すると、データベースが空であることがわかります。
25
Analog File

私は同じ問題を抱えていましたが、私の解決策は、データベースの変更のためにアプリケーションを削除して再度インストールすることでした。

42
edzio27

シミュレーターからアプリを削除して解決し、再度実行しました。以前のバージョンのアプリにはコアデータが含まれていないため、このようになると思います。

3
surga

テスト中にこのエラーを確認しました。一時的なNSManagedObjectContextsをどこにもかけずにスピンアップしたところ、ARCによってコンテキストがランダムに割り当て解除されていました。

うまくいったのは、テストでMOCへの参照を保持し、テストごとにそれをリセットすることでした。

これがテスト以外の状況にどの程度関連しているかはわかりませんが、特に子/兄弟コンテキストを使用している場合は、それらが実際にまだそこにあることを確認する価値があります。 :P

1
DesignatedNerd

私も同じ問題を抱えていました。 理由エラーが発生したのは、マイナーな変更を行ったためですCoreDataエンティティスキーマの変更(基本的に、2〜3個の新しい属性を追加しました)。実行するまでエラーが発生しないため、忘れていました。つまり、以前に実行されていたアプリには、以前のスキーマの永続ストアが既に存在していました。したがって、新しいスキーマは同じストアを指しています。これが、新しい属性にアクセスしようとするときにエラーを実行する理由です。

ソリューションデバイス/シミュレータからアプリを削除し、再インストールします。 (新しいビルドには新しいスキーマが含まれるため、クラッシュしません。)

1
Priyanka

Let moc = DataController()。managedObjectContextをfunc seedPerson()内に残すのではなく、クラスの先頭に移動することで解決しました

1
Arkelyan

私もこの問題にこだわっています。そのため、最初にコアデータ移行コードを確認しました。コードは私の場合は正しかったので、デバイスからアプリを削除して再インストールしました。そしてそれは機能します。

0
bittu

再更新します。 XCODE 4.6.3およびMACOSX 10.9.5:

この問題を解決するために、xcodeから派生したデータの場所にある製品に関連するアプリディレクトリを削除しました。

rm -rd/Users // Library/Developer/Xcode/DerivedData /。どうやら、データはオブジェクトモデルで遊んだ後にめちゃくちゃになっています。

0
mdohmen