ios objective-c cocoa-touch core-data nssortdescriptor

ios - ¿Ordenar el resultado de NSFetchedResultsController basado en una matriz?



objective-c cocoa-touch (2)

Me gustaría construir un NSPredicate o NSSortDescriptor (búsqueda de datos centrales) que esté basado en el contenido de una matriz.

La matriz constará de userId:s en el orden correcto:

[1, 2, 5, 3];

Me gustaría presentar el resultado para mi NSFetchedResultsController en el mismo orden.

Así lo haré:

  1. Obtenga los usuarios correctos (lo he hecho)
  2. Ordene la lista de usuarios según mi matriz ordenada con userId s.

¿Es esto posible y cómo puedo hacerlo?


Creo que eso no es posible. La ordenación de los resultados de una solicitud de recuperación (para una tienda basada en SQLite) se realiza en el nivel SQLite, y puede usar solo atributos persistentes almacenados en la base de datos. El descriptor de clasificación no puede usar funciones o variables de Objective-C.

Entonces cualquiera

  • agrega un atributo adicional a su entidad que describe el orden previsto (si eso es posible), o
  • usted ordena los resultados de acuerdo con sus necesidades después de obtenerlos (lo que significa que ya no puede usar un controlador de resultados obtenido para el seguimiento automático de cambios). Tal vez pueda usar el método descrito aquí: https://.com/a/15618277/1187415 .

La respuesta anterior no es exactamente verdad. Puedes hacer lo que quieras, pero es un poco complicado.

  1. Crear una categoría en NSNumber (ID de usuario es un número, ¿verdad?)
  2. Coloque una variable + global del tipo NSArray en la categoría usando objc_setAssoc ....

    @interface NSNumber(MyExtension) + (NSArray *) orderingArray; + (void) setOrderingArray: (NSArray *)array; - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber; @end int keyVar = 0; @implementation NSNumber(MyExtension) + (NSArray *) orderingArray { return objc_getAssociatedObject(self, &keyVal); } + (void) setOrderingArray: (NSArray *)array { objc_setAssociatedObject(self, &keyVal, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber; { NSArray *a = [self.class orderingArray]; if(!a) return NSOrderedSame; return [@([a indexOfObject:self]) compare: @([a indexOfObject:theOtherNumber])]; }

  3. Establezca la matriz en alguna parte:

    [NSNumber setOrderingArray:myArrayWithKeys];

  4. Use el descriptor de clasificación de tipo:

    [NSSortDescriptor sortDescriptorWithKey:@"userId" ascending:YES selector @selector(myOwnCompareMethodUsingArray:)]

Aparentemente, esto funcionará, ya que funciona para cadenas con localizedCaseInsensitiveCompare: sin embargo, degradará el rendimiento de la consulta si es lo suficientemente grande y anulará cualquier optimización de fetchLimit / fetchOffset. Recuerde que el campo en el que está operando debe ser único; de lo contrario, se irá al infierno.