CoreData'此NSPersistentStoreCoordinator没有持久存储。它不能执行保存操作。 [英] CoreData 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.'

查看:109
本文介绍了CoreData'此NSPersistentStoreCoordinator没有持久存储。它不能执行保存操作。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注这些说明,以帮助将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] ;

//迁移datamodel
NSDictionary * options = nil;

//这需要匹配权限和配置文件
NSURL * cloudURL = [fileManager URLForUbiquityContainerIdentifier:@J9VXW4WCE8.com.company.appname];
NSString * coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@data];
if([coreDataCloudContent length]!= 0 ){
// iCloud可用
cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];

options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption ,
[NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,
@appname.store,NSPersistentStoreUbiquitousContentNameKey,
cloudURL,NSPersistentStoreUbiquitousContentURLKey,
nil];
}
else
{
// iCloud不可用
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(@异步添加持久存储!);
[[NSNotificationCenter defaultCenter] postNotificationName:@RefetchAllDatabaseDataobject: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]){
//更新以适当地处理错误。
NSLog(@未解析的错误%@,%@,错误,[错误userInfo]);
exit(-1); // Fail
}
}
}

在这个方法,控制台给我这个消息:

 'NSInternalInconsistencyException',原因:'这NSPersistentStoreCoordinator没有持久存储。它不能执行保存操作。'

我不知道该怎么办, p>

编辑:控制台日志如下:



启动应用程序后,我会收到:

  2012-08-22 17:39:47.906 appname [24351:707]异步添加持久存储! 
2012-08-22 17:39:47.955 appname [24351:707]异步添加持久存储!

当应用程式崩溃时执行以下操作:

  2012-08-22 17:41:31.657 appname [24351:707] ***由于未捕获异常NSInternalInconsistencyException终止应用程序,原因:'此NSPersistentStoreCoordinator没有持久存储。它不能执行保存操作'
***第一掷调用堆栈:
(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)
终止调用抛出异常(lldb)


解决方案

你可能从两个(或多个)不同的线程调用 persistentStoreCoordinator 方法。直接或间接。



这种方法不是线程安全的。



这可能是你有其他方法具有相同的问题。通常, managedObjectContext 存在,并以类似的方式写。



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


  • 使用 @synchronize 使这些方法线程安全

  • 将初始化代码移出它们并进入init方法,并将其修改为assert /除非ivar nil



    • 您可能也做错了的第二件事是修改上下文(例如,添加新的托管对象),然后尝试保存它,在存储之前



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




      • 如果您需要添加受管理的对象,您不必向该上下文中添加任何受管对象,除非您知道它中至少已有一个受管对象(意味着该商店已加载)

      • 对象到上下文,而不检查是否有一个已经存在(例如,最初创建空存储之后),确保存储已经初始化(例如,当您获得 RefetchAllDatabaseData 通知,您注意到数据库为空)。


      I have been following these instructions to help integrate iCloud support with CoreData and I am getting some errors.

      I have this in my 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;
      }
      

      In another view controller I create an instance of my AppDelegate, create an object and call [appDelegate saveContext]; This is where the app crashes. This has always worked perfectly (up until now, adding iCloud support).

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

      So it crashes at this method, and the console gives me this message:

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

      I don't know what to do, help!

      EDIT: Console log below:

      Upon launching the app, I get:

      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!
      

      Followed up when the app crashes with:

      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) 
      

      解决方案

      You are probably calling persistentStoreCoordinator method from two (or more) different threads. Either directly or indirectly.

      As written that method is not thread safe.

      It may be you have other methods with the same problem. Typically managedObjectContext exists and is written in a similar way.

      There are two ways to solve this problem:

      • use @synchronize to make those methods thread safe
      • move the initialization code out of them and into an init method and modify them to assert/except if the ivar is nil

      The second thing that you may also be doing wrong is to modify the context (for example adding new managed objects to it) and then trying to save it, before the store has been initialized.

      To solve this make sure you do either one of the following:

      • you do not add any managed object to the context unless you know there is already at least one managed object in it (implying the store is loaded)
      • if you need to add a managed object to the context without checking that there's one already (for example after you initially create the empty store), make sure the store has been initialized already (for example do it when you get the RefetchAllDatabaseData notification and you notice the database is empty).

      这篇关于CoreData'此NSPersistentStoreCoordinator没有持久存储。它不能执行保存操作。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆