2011-06-30 15 views
5

Tengo una entidad CoreData con dos atributos. Uno llamado 'posición' el otro llamado 'posiciónCambio'. Ambos son enteros donde el atributo de posición es la posición actual y el cambio de posición es la diferencia entre la posición anterior y la nueva posición. Esto significa que el cambio de posición puede ser negativo.Ordenando cambios en la posición de los datos centrales con descripciones de clasificación para iPhone

Ahora me gustaría ordenar por positionChange. Pero me gustaría ignorar los valores negativos. Actualmente lo estoy ordenando de forma descendente, lo que dará el resultado: 2, 1, 0, -1, -2. Pero lo que estoy buscando es obtener este resultado: 2, -2, 1, -1, 0.

¿Alguna idea sobre cómo resolver esto usando las descripciones de clasificación?


EDITAR

Me dieron 2 clases, una llamada DataManager y el otro que contiene mi categoría NSNumber (positionChange es de tipo NSNumber).

En DataManager tengo un método llamado 'fetchData: donde estoy ejecutar mi solicitud de búsqueda con un descriptor para ordenar:

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:managedObjectContext]; 
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 

que estoy haciendo algunas cosas más a la solicitud, pero eso no es interesante para este problema

categoría

Mi NSNumber debe ser exactamente igual a la que envió: En el .h:

@interface NSNumber (AbsoluteValueSort) 
- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber; 
@end 

Y en el .m:

@implementation NSNumber (AbsoluteValueSort) 

- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber 
{ 
    return [[NSNumber numberWithFloat:fabs([self floatValue])] compare:[NSNumber numberWithFloat:fabs([otherNumber floatValue])]]; 
} 

@end 

Cuando llamo fetchData en mi objeto DataManager Me sale este error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: comparePositionChange:' 

¿Alguna idea de lo que podría ser el caso? He incluido mi archivo de encabezado de categoría NSNumber en mi clase DataManager.

+0

¿Puedes agregar un campo 'absolutePositionChange' al modelo y poblarlo (en el setter para' positionChange', si hay uno) con 'abs (positionChange)'? Puede usar ese campo en su descriptor de ordenación. –

Respuesta

2

probar esto, suponiendo que su positionChange es un NSNumber:

@interface NSNumber (AbsoluteValueSort) 

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber; 

@end 

seguido de:

@implementation NSNumber (AbsoluteValueSort) 

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber 
{ 
    return [[NSNumber numberWithFloat: fabs([self floatValue])] compare:[NSNumber numberWithFloat: fabs([otherNumber floatValue])]]; 
} 

@end 

y luego hacer esto:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)]; 

y ordenar con ese descriptor. Si desea hacerlo de modo que -2 sea siempre después de 2, o 5 sea siempre después de -5, puede modificar comparePositionChange: para devolver NSOrderedAscending en los casos en que un número es el negativo del otro.

+0

¿Es posible llamar a un método de categoría entre objetos? Lo que quiero decir es que mi descriptor de clasificación está ubicado en una clase diferente de la categoría NSNumber. Llamando compararPositionChange: con su ejemplo anterior no funcionará. ¿Ves mi punto? – Anonymous

+0

Solo incluya el archivo que tenga la categoría NSNumber y debería funcionar. La categoría no está "en" ninguna clase. – med200

+0

La categoría está dentro de la clase NSNumber. Llamarlo con su ejemplo implicará que la categoría se implementa dentro de la clase NSSortDescriptor. De lo contrario, la aplicación se bloqueará con NSInvalidArgumentException con el motivo: 'selector no admitido'. Una inclusión simple no funcionará en este caso. A menos que esté haciendo algo mal. ¿Has probado tu solución? – Anonymous

5

El motivo por el que el código falla con el error unsupported NSSortDescriptor selector es que está utilizando un almacén de datos SQLite e intenta usar un método Cocoa como descriptor de clasificación. Con una tienda SQLite, los descriptores de clasificación se traducen sobre la marcha en SQL y la clasificación se realiza mediante SQLite. Eso realmente ayuda al rendimiento, pero también significa que la clasificación se realiza en un entorno que no sea de Cacao, donde su método de comparación personalizado no existe. Ordenar de esta manera solo funciona para los métodos comunes conocidos y no para el código Cocoa arbitrario.

Una solución simple sería realizar la búsqueda sin ordenar, obtener la matriz de resultados y ordenarla. Las matrices se pueden ordenar usando los métodos de Cocoa que quieras, así que la categoría de med200 debería ser útil allí.

También podría cambiar de un almacén de datos SQLite a un almacén binario, si su conjunto de datos no es muy grande.

Cuestiones relacionadas