2012-08-22 16 views
16

He estado siguiendo las instrucciones these para ayudar a integrar el soporte de iCloud con CoreData y estoy obteniendo algunos errores.CoreData 'Este NSPersistentStoreCoordinator no tiene tiendas persistentes. No puede realizar una operación de guardado '.

tengo unas pocas cosas en mi 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; 
} 

En otro controlador de vista puedo crear una instancia de mi AppDelegate, cree un objeto y lo llaman [appDelegate saveContext]; Aquí es donde la aplicación se bloquea. Esto siempre ha funcionado perfectamente (hasta ahora, agregando soporte para 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 
     } 
    } 
} 

Por lo tanto, se estrella en este método, y la consola me da este mensaje:

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

no sé qué hacer, ayuda!

EDIT: por debajo de registro de la consola:

Al lanzar la aplicación, me sale:

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! 

un seguimiento cuando la aplicación se bloquea con:

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) 
+0

¿Ya ha finalizado el hilo de fondo (que obtiene la tienda persistente de iCloud) antes de guardar el contexto? –

+0

¿Cuál es la mejor manera de verificar esto? –

+0

Su código hace un 'NSLog (@" tienda persistente añadida asíncronamente ");' cuando el hilo de fondo ha terminado, por lo que debería ver eso. –

Respuesta

22

Usted probablemente está llamando persistentStoreCoordinator método de dos (o más) hilos diferentes. Ya sea directa o indirectamente.

Como está escrito, ese método no es seguro para subprocesos.

Puede ser que tenga otros métodos con el mismo problema. Normalmente existe managedObjectContext y está escrito de una manera similar.

Hay dos maneras de resolver este problema:

  • uso @synchronize para hacer esos métodos seguros para subprocesos
  • mover el código de inicialización de ellos y en un método init y modificarlos para hacer valer/excepto si el Ivar es nil

la segunda cosa que también puede estar haciendo mal es modificar el contexto (por ejemplo, la adición de nuevos objetos gestionados a él) y luego tratar de salvarla, antes de que la tienda ha sido initiali zed.

para resolver este asegúrese de hacer cualquiera de las siguientes:

  • no se agrega ningún objeto administrado al contexto a menos que sepa que ya hay al menos un objeto administrado en ella (lo que implica la tienda está cargado)
  • si necesita agregar un objeto administrado al contexto sin verificar que ya haya uno (por ejemplo, después de crear inicialmente la tienda vacía), asegúrese de que la tienda ya se haya inicializado (por ejemplo, hágalo cuando consiga la notificación RefetchAllDatabaseData y verá que la base de datos está vacía).
+0

Estoy enfrentando el mismo problema como Josh Kahane, pero díganme cómo puedo usar "sincronizar" en persistentStoreCoordinator? por favor respóndeme –

40

Tuve el mismo problema y mi solución fue eliminar la aplicación e instalarla de nuevo debido a modificaciones en la base de datos.

+0

Pensarías que ahora recordaría hacer esto.Gracias por recordármelo rápidamente –

+0

funcionó para mí ... gracias – Saranjith

+1

Esto solo funciona si no has iniciado tu aplicación en la tienda de aplicaciones. De lo contrario, se resolverá en una aplicación bloqueada para todos los usuarios que descargaron la versión anterior y la actualizaron con su nueva versión. –

0

Actualizar re. XCODE 4.6.3 y MacOSX 10.9.5:

Para resolver el problema me quita el directorio de aplicación en relación con el producto en Xcode derivados ubicación de los datos:

rm -RD/Usuarios // Biblioteca/desarrollador/Xcode/DerivedData /. Aparentemente, los datos se arruinan después de jugar con el modelo de objetos.

1

resolver moviendo el moc Let = DataController() managedObjectContext. A la parte superior de la clase en lugar de dejar el interior de la seedPerson func()

2

Lo resuelto mediante la eliminación de la aplicación del simulador y ejecutarlo de nuevo. Supongo que sucede porque la versión anterior de la aplicación no tiene datos básicos.

0

Vi este error durante la prueba cuando configuré algunos NSManagedObjectContext s temporales sin colgarlos en ninguna parte - ARC eliminó el contexto de debajo de mí al azar.

Lo que terminó funcionando fue mantener una referencia al MOC en las pruebas y restablecerlo para cada prueba.

No estoy seguro de qué tan relevante es esto para las circunstancias que no son de prueba, pero especialmente si está utilizando contextos de niños/hermanos, vale la pena asegurarse de que en realidad todavía están allí. : P

0

También me he atascado con este problema. Para eso, primero compruebo el código de migración de datos centrales. Como el código era correcto en mi caso, eliminé mi aplicación del dispositivo y la reinstalé. Y funciona.

0

Tuve el mismo problema. El motivo que estaba obteniendo el error era porque había hecho algunos cambios menores en mi esquema de Entidad CoreData (Básicamente agregué 2-3 nuevos atributos). Y lo olvidé porque no da ningún error hasta que lo ejecutemos. Entonces, lo que sucede es que la aplicación que se estaba ejecutando anteriormente ya tenía la tienda persistente con el esquema anterior. Entonces, el nuevo esquema apunta a la misma tienda. Es por eso que tenemos el error cuando lo ejecutamos mientras tratamos de acceder a los nuevos atributos.

Solución: Eliminar la aplicación del dispositivo/simulador. Y vuelva a instalarlo. (La nueva compilación tendrá el nuevo esquema y, por lo tanto, no se bloqueará.)

Cuestiones relacionadas