2009-07-01 22 views
19

Los Core Data Documentation establece que:cómo ordenar datos básicos propiedades inverosímiles

La petición de recuperación asociado a la propiedad [descabellada] puede tener un ordenamiento especie, y por lo tanto la propiedad inverosímil puede ser ordenada.

¿Cómo especifico las descripciones de clasificación para la propiedad recuperada en el editor de modelo de datos de Xcode? No puedo encontrar un campo relevante en ninguna parte. Estoy desarrollando para la plataforma iPhone, si esto hace alguna diferencia.

Si esto no es posible a través del editor de modelos gráficos, ¿cómo hago para modificar la solicitud de búsqueda de la propiedad obtenida en el código para que tenga un descriptor de clasificación?

+0

agrega la etiqueta iphone – Dan

Respuesta

5

La herramienta de modelado no parece tener una forma de establecer los descriptores de clasificación en la solicitud de búsqueda.

Debería ser posible [1], después de cargar el modelo pero antes de asociarlo con un coordinador de tienda persistente, buscar las descripciones de propiedad buscadas para las cuales desea controlar el orden y reemplazar sus solicitudes de recuperación con fetch solicitudes que tienen descripciones de clasificación establecidas en ellas.

[1] En principio esto debería funcionar. En la práctica, no lo he hecho o lo he probado.

+1

Es una lástima que la herramienta de modelado no tenga esta característica, parece que en gran medida disminuye la utilidad de poder especificar solicitudes de búsqueda en la herramienta. –

+0

Esta pregunta proporciona un ejemplo de crear programáticamente una NSFetchedPropertyDescription y agregarla a un NSManagedObjectModel: http://stackoverflow.com/questions/5638364/how-do-i-create-an-nsfetchedpropertydescription-programmatically –

13

No las especifica en el editor gráfico (hasta donde yo sé).

Los especifica en el código donde realiza la búsqueda.

NSFetchRequest* request = [[NSFetchRequest alloc] init]; 
NSEntityDescription* entity = [NSEntityDescription entityForName:@"whatYouAreLookingFor" 
    inManagedObjectContext:self.managedObjectContext]; 
[request setEntity:entity]; 

// here's where you specify the sort 
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] 
           initWithKey:@"name" ascending:YES]; 
NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects: sortDescriptor, nil] autorelease]; 
[request setSortDescriptors:sortDescriptors]; 
[sortDescriptor release]; 

fetchedResultsController = [[NSFetchedResultsController alloc] 
       initWithFetchRequest:request 
       managedObjectContext:self.managedObjectContext 
       sectionNameKeyPath:nil 
          cacheName:@"myCache"]; 
+0

Esto es correcto más arriba. Tienes que agregar NSSortDescriptor, no puedes especificar esto en tu modelo de datos, perdón. Sí, es largo, pero esto es exactamente lo que estoy haciendo en mi aplicación de datos básicos. –

+25

Lo anterior está bien para una solicitud de recuperación normal, pero no tiene nada que ver con la pregunta, que trata sobre las propiedades obtenidas y su clasificación. – Hunter

0

Lamentablemente, la capacidad de ordenar es algo limitada. Por ejemplo, no puede tomar un campo que es un NSString que contiene un número, y ordenarlo numéricamente, al menos no con un almacén de respaldo de SQLite. Sin embargo, siempre y cuando esté ordenando alfabéticamente en cadenas, numéricamente solo en valores almacenados como números y demás, el NSSortDescriptor aplicado a la solicitud de búsqueda funciona bien.

+1

Puede escribir métodos de clasificación más sofisticados, usando initWithKey de NSSortDescriptor: ascendente: selector: –

35

Puede realmente tomar la propiedad de modelo recuperada y agregarle las descripciones de clasificación (nuevamente, en el código). Hice esto en el método estándar que XCode genera en su AppDelegate si elige una de las plantillas con Core Data:

Por cierto. Esto ordena TODAS las propiedades recuperadas en TODOS los modelos en su modelo de datos. Podrías volverte elegante y adaptativo, pero fue la manera más concisa de manejar los 7 modelos separados que cada uno había obtenido propiedades que necesitaban clasificarse por nombre. Funciona bien.

/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created by merging all of the models found in the application bundle. 
*/ 
- (NSManagedObjectModel *)managedObjectModel { 

    if (managedObjectModel != nil) { 
     return managedObjectModel; 
    } 
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  

    // Find the fetched properties, and make them sorted... 
    for (NSEntityDescription *entity in [managedObjectModel entities]) { 
     for (NSPropertyDescription *property in [entity properties]) { 
      if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) { 
       NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property; 
       NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest]; 

       // Only sort by name if the destination entity actually has a "name" field 
       if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"name"]) { 
        NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]]; 
        [sortByName release]; 
       } 
      } 
     } 
    } 

    return managedObjectModel; 
} 
+5

Además, la codificación de valores clave también puede ayudar con esto, por ejemplo: \t [managedObjectModel setValue: sortDescriptorArray forKeyPath: @ "entitiesByName.EntityName.propertiesByName. fetchPropertyName.fetchRequest.sortDescriptors "]; –

-1

Jeff, si las cadenas están alineadas a la derecha, puede ordenar las cuerdas; "123"> "23" y así sucesivamente. Pero iirc ascii space está detrás de los números, y si es así, entonces lo que haría sería crear una propiedad dinámica que sea un NSNumber (que admita el método compare:), y use el método numberFromString: para hacer un número a partir de la cadena. Luego puede especificar el campo numérico en el orden. En la interfaz:

@property NSString *stringIsaNumber; // in the data model 
@property NSNumber *number; 

en la implementación:

@dynamic stringIsaNumber; 
- (NSNumber *) number ; 
{ return [self.stringIsaNumber numberFromString]; } 
- (void) setNumber:(NSNumber *)value; 
{ self.stringIsaNumber = [NSString stringWithFormat:@"%5i",value) } 

ps PLZ perdona los errores de codificación, esto es de la parte superior de la cabeza.

5

Usando gran respuesta de Tim Shadel añadí per-NSManagedObject subclase de clasificación ...

... en Tier.m (que es una subclase NSManagedObject) ...

+ (void)initialize 
{ 
    if(self == [Tier class]) 
    { 
     NSFetchedPropertyDescription *displayLessonPropertyDescription = [[[Tier entityDescription] propertiesByName] objectForKey:@"displayLesson"]; 
     NSFetchRequest *fetchRequest = [displayLessonPropertyDescription fetchRequest]; 

     NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES]; 
     [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]]; 
     [sortByName release]; 
    } 
} 
+1

¿Dónde se define - [Tier entityDescription] ?! – hatfinch

+0

Ah, estoy usando RestKit en esta situación que tiene un montón de métodos de conveniencia como ese. Echa un vistazo a su categoría NSManagedObject + ActiveRecord. – rob5408

+0

No estoy seguro de por qué se rechazó la edición de @ AndyOS, definitivamente tuve un error en mi código. – rob5408

0

poner esto en su NSManagedObject subclase:

+ (void)initialize 
{ 
    if (self != [EntityManagedObjectSubClass class]) return; 
    NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; 
    NSEntityDescription *entityDescription = [managedObjectModel entitiesByName][@"entityName"]; 
    NSFetchedPropertyDescription *fetchedPropertyDescription = [entityDescription propertiesByName][@"fetchedPropertyName"]; 
    NSFetchRequest *fetchRequest = [fetchedPropertyDescription fetchRequest]; 
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortDescriptorKey" ascending:YES]; 
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
} 

Reemplazar EntityManagedObjectSubClass, entityName, fetchedPropertyName y sortDescriptorKey con yo tu propio material.

Cuestiones relacionadas