CoreData'这个NSPersistentStoreCoordinator没有持久存储。它无法执行保存操作。

时间:2012-08-22 14:51:46

标签: iphone objective-c ipad core-data icloud

我一直在关注these指令,以帮助将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;
}

在另一个视图控制器中,我创建了一个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) 

9 个答案:

答案 0 :(得分:43)

我遇到了同样的问题,我的解决方案是删除应用程序并因数据库中的修改而再次安装它。

答案 1 :(得分:22)

您可能正在从两个(或更多)不同的线程调用persistentStoreCoordinator方法。无论是直接还是间接。

如上所述,该方法不是线程安全的。

您可能有其他方法遇到同样的问题。通常managedObjectContext存在,并以类似的方式编写。

有两种方法可以解决这个问题:

  • 使用@synchronize使这些方法保持线程安全
  • 将初始化代码移出它们并进入init方法并修改它们以断言/除非ivar是nil

您可能也做错的第二件事是修改上下文(例如向其添加新的托管对象),然后在初始化商店之前尝试保存它。

要解决此问题,请确保执行以下任一操作:

  • 您不会向上下文添加任何托管对象,除非您知道其中至少已有一个托管对象(暗示该商店已加载)
  • 如果您需要将托管对象添加到上下文而不检查是否已存在(例如,在您最初创建空商店之后),请确保该商店已经初始化(例如,当您获得{时执行此操作) {1}}通知,您注意到数据库是空的。)

答案 2 :(得分:2)

我通过从模拟器中删除应用程序并再次运行来解决它。我想这是因为之前版本的应用程序中没有核心数据。

答案 3 :(得分:1)

通过将let moc = DataController()。managedObjectContext移动到类的顶部而不是留在func seedPerson()内部来解决

答案 4 :(得分:1)

我在测试过程中看到了这个错误,当我将一些临时的NSManagedObjectContext旋转而没有在任何地方挂起它们时 - 上下文会被ARC随机释放出来。

最终工作是在测试中保留对MOC的引用并为每次测试重置它。

不确定这与非测试环境有多相关,但特别是如果您使用的是儿童/兄弟情境,那么值得确保他们确实仍在那里。 :P

答案 5 :(得分:1)

我遇到了同样的问题。 原因我收到错误是因为我在CoreData Entity架构中做了一些小的更改(基本上我添加了2-3个新属性)。我忘记了它,因为它在我们运行它之前没有给出任何错误。所以会发生的事情是,之前运行的应用程序已经拥有了先前架构的持久存储。所以新架构指向同一个商店。这就是为什么我们在尝试访问新属性时运行它时会出现错误。

解决方案从设备/模拟器中删除应用。并重新安装。 (新版本将具有新架构,因此不会崩溃。)

答案 6 :(得分:0)

更新。 XCODE 4.6.3和MACOSX 10.9.5:

要解决此问题,我删除了与xcode派生数据位置中的产品相关的app目录:

rm -rd / Users // Library / Developer / Xcode / DerivedData /。 显然,在使用对象模型后数据会搞乱。

答案 7 :(得分:0)

我也遇到了这个问题。为此我首先检查核心数据迁移代码由于代码在我的情况下是正确的,我已从设备删除我的应用程序并重新安装它。它有效。

答案 8 :(得分:0)

对我来说,我发现addPersistentStoreWithType总是返回nil。因此,持久性存储未成功创建。 然后,我打印storeURL

~/Library/Developer/CoreSimulator/Devices/1F8C6299-1F80-4212-9FE2-CA33BD365851/data/Containers/Data/Application/9CA7B7BB-A835-4BC2-B12D-23B84D420F91/Library/Documentation/my-database.sqlite

这是我们不能在其中写入数据的目录。所以我检查了代码,发现了一个愚蠢的错误。 enter image description here

  • 我应该使用NSDocumentDirectory而不是NSDocumentationDirectory。 Xcode中的代码完成功能在文档目录枚举之前提供了文档目录。

  • 当我使用 NSDocumentationDirectoryNSPersistentStoreCoordinator总是尝试在.../Library/Documentation/my-database.sqlite中创建持久存储,这是无效的路径。

  • 相反,正确的路径应为.../Documents/BeeLocation.sqlite