Pregunta

Imagine una entidad CoreData (por ejemplo, llamada searchEngine).
NSManagedObjectContext gestiona algunas " instancias " de esta entidad.
El usuario final podrá seleccionar su "standard searchEngine" con un NSPopupButton.
El selected object de NSPopupButton debe estar vinculado a NSUserDefaults.
El problema:

  

1) @try {save}

     
    

a) Si intenta guardar el " instancia " directamente a NSUserDefaults llega algo como esto:

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60  ; data: {
    url = "http://google.de/";
    someAttribute = 1;
    name = "google";
})' of class 'searchEngine'.

         

b) Si intenta convertir la " instancia " a NSData viene esto:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0

         

Entonces, ¿alguna idea de cómo obtener estas entidades en datos compatibles con plist?

  
     

2) @try {registerDefaults}

     
    

Por lo general, el método registerDefaults: se implementa en + (void)initialize. El problema aquí es que se llama a este método antes de que CoreData cargue las entidades guardadas de su base de datos. Entonces, no puedo establecer un valor predeterminado para un objeto inexistente, ¿verdad?

  

Lo sé, preguntas largas ... pero: prueba {[me proporcionar: detalles]}; D

¿Fue útil?

Solución

No querrá intentar archivar una entidad de datos centrales y almacenarla. En su lugar, almacenaría la clave o algún otro atributo conocido y lo usaría para obtener la entidad cuando se inicie la aplicación.

Algún código de ejemplo (ligeramente modificado del ejemplo publicado en el Guía de programación de datos básicos ):

NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
    entityForName:@"SearchEngine" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];

NSPredicate *predicate = [NSPredicate predicateWithFormat:
    @"engineName LIKE[c] '%@'", selectedEngineName];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
    // Deal with error...
}

De esta manera, guarda el nombre en los valores predeterminados del usuario y busca la entidad cuando sea necesario.

Otros consejos

Si necesita almacenar una referencia a un objeto administrado específico, use la representación URI de su ID de objeto administrado:

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];

Puede guardar la URL en los valores predeterminados del usuario.

Para recuperar el objeto administrado, use:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];

La única advertencia es que debe asegurarse de que la ID del objeto administrado original sea permanente; esto no es un problema si ya ha guardado el objeto; de lo contrario, puede usar obtainPermanentIDsForObjects:error:.

Aquí está la forma más limpia y corta de hacer esto actualmente usando los métodos setURL y getURL agregados en 4.0 para evitar llamadas adicionales a NSKeyedUnarchiver y NSKeyedArchiver:

Configuración :

 + (void)storeSomeObjectId:(NSManagedObjectID *)objectId
 {
     [[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation] 
                                            forKey:@"someObjectIdKey"];
     [[NSUserDefaults standardUserDefaults] synchronize];
 }

Getter:

 + (SomeManagedObject *)getObjectByStoredId
 {
     NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"];
     NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri];
     SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId];
 }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top