7

Me encuentro con opciones de diseño como este a menudo y me cuesta un poco; Estoy buscando otras perspectivas.¿Mejor alternativa para objetos Objective-C "solo-datos"?

A menudo quiero mantener listas de, o pasar fragmentos de estado que son básicamente solo conjuntos de valores. Los valores tienden a ser tipos primitivos: flotantes, NSTimeIntervals, CGPoints, etc.

Mi primera inclinación suele ser crear estructuras en C para estos conjuntos de propiedades, p.

typedef struct _STATE { 
    float foo; 
    NSTimeInterval elapsed; 
    CGPoint point; 
} STATE; 

etc.

Pero las estructuras C no se llevan bien con las clases nativas de recolección de cacao (NSArray, NSSet, NSDictionary), y el uso de overmany de ellos para realizar un seguimiento del estado de las porciones se siente como que va en contra el grano del resto de mi código compatible con Cocoa: termino teniendo y administrando matrices de estructuras, y pasando indicadores de estructura en mensajes, etc.

Por otro lado, dado que el rendimiento en bruto no es necesariamente crítico , Podría codificar estos valores en un NSDictionary, envolviéndolos en NSValue o NSNumber, pero la sintaxis resultante es casi terso, y un poco frágil, que requiere el tipo y el nombre de la corrección en tiempo de ejecución, tanto para la inserción y la búsqueda:

[stateDict setObject:[NSNumber numberWithFloat:foo] forKey:@"bar"]; 
... 
float something = [[stateDict objectForKey:@"bar"] floatValue]; 

y algunos tipos, como NSTimeInterval, sólo son capaces de ser utilizado con algunos (discutible) piratería (tipocast para duplicar en ese caso).

Finalmente, pude crear objetos contenedores solo de datos, con datos de miembros privados y solo getters/setters. (Estos se llamarían "beans" en Java). Estos son más lacónicos que los diccionarios, más Cocoa que estructuras, pero me parecen excesivos, especialmente si solo los necesito como "clases internas" que se usan para la administración del estado. interno a un solo tipo de objeto.

¿Cómo es que usted, gran público de programación de Cocoa, hace esto?

Respuesta

14

Dependiendo de la situación, ejecuto el uso de clases NSDictionary para datos arbitrarios o creo clases de contenedor (las etiquetas @ property/synthesize en Objective C lo hacen realmente fácil). Mediante el uso de ObjC para el archivo de cabecera:

@interface StateObject : NSObject { 
    NSNumber *foo; 
    NSTimeInterval *elapsed; 
    CGPoint point; 
} 

@property (retain) NSNumber *foo; 
@property (retain) NSTimeInterval *elapsed; 
@property (copy) CGPoint point; 

@end 

Uno puede entonces utilizar @synthesize <variable> en el archivo .m para crear automáticamente los setters/captadores. Entonces, mientras NSNumbers anónimos siguen siendo intratable, puede hacerlo:

myStateObject.foo = [NSNumber numberWithFloat:7.0]; 

Esto debe tomar la mayor parte del dolor de distancia, y permitirá utilizar las clases de colección de cacao a mejores datos barajar.

+4

+1.La creación de clases modelo casi siempre es el camino a seguir a menos que tenga un código muy crítico para el rendimiento donde la sobrecarga de usar objetos ocasione problemas. –

+3

Gracias por este Matt. En este escenario, ni siquiera necesita envolver flotantes con NSNumber-- uno puede usar la sintaxis @property para acceder a los tipos primitivos. (Lo mismo ocurre, por supuesto, con NSTimeInterval, que pasa a ser un flotador primitivo typedef'd). –

2

No necesariamente respaldando este enfoque como "mejor", pero hay un término medio entre sus propuestas: cree estructuras C para contener la información y luego envuelva las estructuras en objetos NSValue cuando necesite ponerlas en estructuras de datos Cocoa . Puede ver que UIKit hace esto en algunos casos con estructuras como CGPoint en notificaciones (y estoy seguro de que AppKit también lo hace).

Consulte "Uso de valores" en Number and Value Programming Topics for Cocoa para obtener más información al respecto.

Cuestiones relacionadas