2012-03-22 11 views
6

Esto me está volviendo loco, literalmente.iOS Core Data cómo comparar correctamente el texto de cadena usando predicados?

Tengo 2 entidades que usan NSStrings como atributo único.

¿Cuál es la forma correcta de crear un predicado que compare NSStrings?

Actualmente tengo: [NSPredicate predicateWithFormat: @ "unique =% @", uniqueValue];

Tengo la sensación de que esto compara las direcciones del puntero, no los valores reales de las cadenas, pero no puedo confirmarlo. Necesito devolver sí para una coincidencia de cadena exacta.

-(BOOL)uniqueEntityExistsWithEnityName:(NSString*)entityName UniqueKey:(NSString*) uniqueKey UniqueValue:(NSString*)uniqueValue SortAttribute:(NSString*)sortDescriptorAttribute ManagedObjectContext:(NSManagedObjectContext*) context; 
{ 
    BOOL returnValue = NO; 

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName]; 

//what is the correct predates to compare the text an string core data property against a passed in string? 
    request.predicate = [NSPredicate predicateWithFormat:@"unique= %@", uniqueValue]; 

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortDescriptorAttribute ascending:YES]; 
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 

    NSError *error = nil; 
    NSArray *matches = [context executeFetchRequest:request error:&error]; 
    if (!matches) 
    { 
     NSLog(@"Error: no object matches"); 
    } 
    else if([matches count] > 1) { 
     NSLog(@"Error: More than one object for unique record"); 
     returnValue = YES; 

    } else if ([matches count] == 0) { 
     returnValue = NO; 
    } else { 
     returnValue = YES; 
    } 

    return returnValue; 
} 
+0

¿Tiene una sensación o un problema real? Tu código se ve bien Sus datos se obtienen de una base de datos sqlite, ¿cómo debe coincidir con las direcciones del puntero? –

Respuesta

9

Un solo signo igual no es ni siquiera un elemento de comparación en cuanto a la codificación.

Voy a suponer que único es un atributo NSManagedObject.

[NSPredicate predicateWithFormat:@"unique LIKE %@", uniqueValue]; 

Tenga en cuenta que esto distingue entre mayúsculas y minúsculas. Si quieres que sea insensible, puedes poner [c] después de LIKE.

+0

Gracias Kevin, lo probaré! –

+12

un solo signo igual es perfecto para usar en NSPredicate. –

+0

¡Oh! ¡Supongo que estas en lo correcto! Guau, parece extraño que sea el caso (dado que en cualquier otro lugar en la codificación de un solo signo igual es una tarea). –

7

No veo ningún problema con su predicado. Un solo = es perfecto si quiere hacer coincidir cadenas exactas. Si no necesita la coincidencia de comodines, no necesita el LIKE más lento. (Predicate Format String Syntax)

Sin embargo, hay un problema en el código y puede llevar a suposiciones que no son correctas. Tu if/then/else, o al menos el primer mensaje está un poco equivocado. Si obtiene no devuelve una matriz, significa que la recuperación falló, no significa que la recuperación no devolvió objetos.

Debería ser de la misma familia:

if (!matches) 
{ 
    NSLog(@"Error: couldn't execute fetch request %@", error); 
} 
else if([matches count] > 1) { 
    NSLog(@"Error: More than one object for unique record"); 
    returnValue = YES; 
} else if ([matches count] == 0) { 
    NSLog(@"couldn't match objects"); 
    returnValue = NO; 
} else { 
    // [matches count] == 1 
    NSLog(@"matched one object"); 
    returnValue = YES; 
} 

Ah, y me gustaría cambiar el orden de las condiciones. En mi opinión, una estructura como (! Coincide), ([coincide con el conteo] == 1), ([coincide con el conteo] == 0), (más) tiene más sentido y es más fácil también de leer. Pones la condición más importante (porque es lo que realmente quieres) en el último "anónimo".

Cuestiones relacionadas