27

iCloudサポートをCoreDataと統合するためにこれらの手順に従っていますが、いくつかのエラーが発生します。

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

別のViewControllerで、インスタンスを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) 
4

9 に答える 9

41

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

于 2013-02-25T21:47:44.490 に答える
28

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

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

同じ問題を抱えた他の方法があるかもしれません。通常はmanagedObjectContext存在し、同様の方法で記述されます。

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

  • @synchronizeこれらのメソッドをスレッドセーフにするために使用します
  • 初期化コードをそれらから init メソッドに移動し、ivar がnil

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

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

  • 少なくとも 1 つの管理対象オブジェクトが既に存在することがわかっている場合を除き、管理対象オブジェクトをコンテキストに追加しません (ストアが読み込まれていることを意味します)。
  • 管理対象オブジェクトが既に存在することを確認せずにコンテキストに追加する必要がある場合 (たとえば、最初に空のストアを作成した後)、ストアが既に初期化されていることを確認します (たとえば、RefetchAllDatabaseData通知を受け取って気付いたときに実行します)。データベースは空です)。
于 2012-08-22T17:50:48.897 に答える
4

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

于 2016-09-15T22:06:32.280 に答える
1

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

于 2016-06-20T19:32:52.053 に答える
0

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

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

rm -rd /Users//Library/Developer/Xcode/DerivedData/. どうやら、オブジェクト モデルで遊んだ後、データが台無しになるようです。

于 2014-09-22T07:58:40.530 に答える