2011-07-03 19 views
5

He tenido varios casos en los que una clase Objective-C tiene una propiedad que debe ser una clase de colección (normalmente NSArray). ¿Hay una forma estándar de implementar esto? Sería genial poder usar @synthesize para configurar esto. Podría declarar la propiedad como NSMutableArray y @synthesize eso, pero eso no me permite imponer qué tipos de objetos se pueden colocar en la colección, ni impide que el código del cliente modifique la matriz. Lo que suelen hacer es algo como esto:Objetivo C @ propiedad para muchas relaciones

@property(nonatomic, readonly) NSArray *widgets; 

- (void)addWidget:(Widget*)widget; 
- (void)removeWidget:(Widget*)widget; 
... 

La colección se implementa como un NSMutableArray, con un NSArray que contiene el contenido actual pasa de nuevo a la persona que llama. Esto parece una gran cantidad de codificación para lo que debe ser un escenario común. Se necesita hacer aún más codificaciones para establecer la observación del valor clave.

¿Me está faltando algo, o realmente se trata de mucho trabajo para establecer una propiedad de la colección?

Respuesta

1

Puede evitar que el código del cliente modifique su matriz al declarar la propiedad como un NSArray, pero usando un NSMutableArray como mecanismo de almacenamiento. Las directivas @property y @synthesize seguirán funcionando.

No hay realmente una buena manera de garantizar la seguridad de tipo de los objetos devueltos por su matriz, pero los programadores de Objective-C casi nunca se preocupan por eso. Simplemente no es una preocupación común. Si realmente desea asegurarse de que solo entran y salen objetos de un tipo determinado de la matriz, tendrá que escribir una clase contenedora para que NSArray lo haga.

+0

Con el enfoque que describes, aún necesitaré escribir los métodos de agregar/quitar, así que supongo que puedo aplicar el tipo allí. Tendré que probar para ver si eso se encargará del cumplimiento de KVO. Espero que así sea porque ahora estoy manipulando directamente la variable de almacenamiento de la propiedad en lugar de manejar la colección mutable por separado. – brentopolis

+0

También me doy cuenta de que declarar la propiedad como un NSArray en realidad no impide que el código del cliente modifique la matriz, porque el objeto devuelto en realidad es un NSMutableArray. Solo causa advertencias del compilador. – brentopolis

+0

Correcto, cuando declara que la propiedad es de tipo NSArray, el método de acceso sintetizado solo devuelve una instancia retenida-liberada de su objeto interno NSMutableArray. Los usuarios de su API no deberían intentar lanzar ese objeto a NSMutableArray, ya que la API solo promete un NSArray. Sin embargo, si está escribiendo una API pública ampliamente utilizada que puede ser difícil de aplicar. En ese caso, aún puede usar la directiva @synthesize, pero implemente el método getter de modo que devuelva una copia liberada automáticamente de su ivar, p. Ej. 'return [[_myMutableArray copy] liberación automática];' – Ryan

Cuestiones relacionadas