2009-09-17 19 views
10

En mi proyecto de iPhone, deseo escribir una función que compruebe si hay un objeto en mi Core Data ManagedObjectContext con un valor determinado para una propiedad determinada, digamos some_property.Recuperar objeto por propiedad en Core Data

Si ya hay un objeto con some_property == 12, quiero que la función devuelva el objeto, de lo contrario, quiero crear el objeto, o al menos devolver nil.

¿Cómo podría hacer eso?

Respuesta

19

El siguiente fragmento muestra cómo recuperar los objetos que coinciden con un predicado específico. Si no hay tales objetos, el fragmento muestra cómo crear un nuevo objeto, guardarlo y devolverlo.

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourEntityName" inManagedObjectContext:managedObjectContext]; 
    [request setEntity:entity]; 
    // retrive the objects with a given value for a certain property 
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"property == %@", value]; 
    [request setPredicate:predicate]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"yourSortKey" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 



    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
    aFetchedResultsController.delegate = self; 

    NSError *error = nil; 
    NSArray *result = [managedObjectContext executeFetchRequest:request error:&error]; 

    [request release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 


    if ((result != nil) && ([result count]) && (error == nil)){ 
     return [NSMutableArray arrayWithArray:result]; 
    } 
    else{ 
     YourEntityName *object = (YourEntityName *) [NSEntityDescription insertNewObjectForEntityForName:@"YourEntityName" inManagedObjectContext:self.managedObjectContext]; 
      // setup your object attributes, for instance set its name 
      object.name = @"name" 

      // save object 
      NSError *error; 
      if (![[self managedObjectContext] save:&error]) { 
      // Handle error 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

      } 

      return object; 

    } 
+0

wow, eso fue rápido! Déjame probar eso ... – winsmith

+0

¿Cuál es el punto de 'aFetchedResultsController'? ¿Me equivoco al pensar que lo creaste, pero nunca lo uso para hacer nada? – ArtOfWarfare

+0

Tiene razón, en este ejemplo particular NSFetchedResultsController no se usa, pero debe estar en el contexto de una aplicación real (simplifica muchas otras cosas y proporciona un buen mecanismo de almacenamiento en caché). –

2

Es mejor si no realiza una búsqueda múltiple si desea verificar ciertas propiedades en los datos locales. Simplemente haga una solicitud de recuperación usando una matriz precompilada y luego itere o filtre los resultados.

Este es un fragmento de código de Guía de Programación de Datos Básicos "Implementación de Find-o-Crear eficientemente":

// get the names to parse in sorted order 
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"] 
     sortedArrayUsingSelector: @selector(compare:)]; 

// create the fetch request to get all Employees matching the IDs 
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity: 
     [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]]; 
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]]; 

// make sure the results are sorted as well 
[fetchRequest setSortDescriptors: [NSArray arrayWithObject: 
     [[[NSSortDescriptor alloc] initWithKey: @"employeeID" 
       ascending:YES] autorelease]]]; 
// Execute the fetch 
NSError *error; 
NSArray *employeesMatchingNames = [aMOC 
     executeFetchRequest:fetchRequest error:&error];