2012-09-23 71 views
8

Tengo una clase de modelo con algunas composiciones de objetos, y no sé la mejor manera de escribir iteradores para esto. Para ver el problema en más detalles, aquí está la jerarquía (código semi-pseudo):¿Cómo escribir mi propio iterador para una propiedad de colección de una propiedad (con el tipo correcto de conversión)?

Una clase raíz:

MYEntity : NSObject 
@property int commonProperty; 
@property NSArray *childs; //Childs of any kind. 

Algunas subclases concretas:

MYConcreteStuff : MYEntity 
@property int number; 

MYConcreteThing : MYEntity 
@property NSString *string; 

y un objeto de raíz con colecciones de hormigón:

MYRoot : MYEntity 
@property MYEntity *stuff; //Collect only stuff childs here. 
@property MYEntity *things; //Collect only thing childs here. 

Ahora puedo escribir accesos de miembros geniales para las colecciones (en MYEn tity), como:

-(MYEntity*)entityForIndex:(int) index 
{ 
    if ([self.childs count] > index) 
     return [self.childs objectAtIndex:index]; 

    return nil;  
} 

Y aún más accesorios de miembro fundido geniales y bien creados para el objeto raíz.

-(MYConcreteThing*)thingForIndex:(int) index 
{ 
    if ([self.things count] > index) 
     return (MYConcreteThing*)[self.things entityForIndex]; 

    return nil;  
} 

Pero no tengo idea de cómo escribir algunos iteradores de oneliner para dichas colecciones. El código de cliente aspirante es algo así como:

for (MYConcreteThing *eachThing in myRoot.things) 
    eachThing.string = @"Success."; //Set "thingy" stuff thanks to the correct type. 

Estoy pensando en el uso de bloques, pero podría ser una solución corte más limpio. ¿Alguna idea/experiencia?

Respuesta

8

Voy a continuar con los bloques por ahora, eso es bastante sencillo. Ahora prefiero el término enumerar.

un tipo de bloque de cosa de enumeración (asegurando tipo correcto):

typedef void (^MYThingEnumeratorBlock)(MYThing *eachThing); 

Un método empadronador fresco para las cosas en Myroot (de no exponer colecciones):

-(void)enumerateThings:(MYThingEnumeratorBlock) block 
{  
    for (MYThing *eachThing in self.things.childs) 
     block(eachThing); 
} 

Así código de cliente va:

[myRoot enumerateThings:^(MYThing *eachThing) 
{ 
    NSLog(@"Thing: %@", eachThing.string);   
}]; 

Con un poco de macro ordenada:

#define ENUMARATE_THINGS myRoot enumerateThings:^(MYThing *eachThing) 

[ENUMARATE_THINGS 
{ 
    NSLog(@"Thing: %@", eachThing.string); //Cool "thingy" properties.   
}]; 
1

La mejor manera de hacerlo, en mi opinión, sería implementar los métodos que cumplan con la codificación de valor clave para las propiedades de matriz. Esto tendría la ventaja adicional de hacer que tus colecciones sean observables por otros objetos. Puede leerlo al respecto en el apple documentation. Aquí hay una implementación de ejemplo para el conjunto de Cosas en la clase MYRoot. Siéntase libre de personalizar el código en cada método:

// KVC method for read-only array of Things 
- (NSUInteger) countOfThings 
{ 
    return _things.count; 
} 

- (Thing*) objectInThingsAtIndex:(NSUInteger)index 
{ 
    return [_things objectAtIndex:index]; 
} 

// Additional KVC methods for mutable array collection 
- (void) insertObject:(Thing*)thing inThingsAtIndex:(NSUInteger)index 
{ 
    [_things insertObject:thing atIndex:index]; 
} 

- (void) removeObjectInThingsAtIndex:(NSUInteger)index 
{ 
    [_things removeObjectAtIndex:index]; 
} 

para iterar sobre la colección que haría lo siguiente:

for (Thing *thing in [_entity valueForKey:@"things"]) { 
} 

Para añadir una cosa en la matriz que podría hacer

NSMutableArray *children = [_entity mutableArrayValueForKey:@"things"]; 
[children addObject:aThing]; 

Al hacerlo de esta manera, se asegura de que todos los objetos que observen la propiedad @"things" serán notificados de todos los cambios en la matriz. Si llama directamente a los métodos de inserción, no lo harán (esto a veces es útil en sí mismo).

+0

Si las cosas fueran una matriz, entonces se podría hacer simplemente por (cosas * de cosasMi.Objetos), sin material de KVO. – Geri

+0

Pero las cosas son una entidad que tiene una matriz llamada childs. Por eso necesito algo de indirección. – Geri

+0

Modifiqué la pregunta para ser más claro. O al menos exacto. :) – Geri

Cuestiones relacionadas