2011-04-13 13 views
18

Existen varias situaciones en las que puede anular la propiedad de una superclase.¿Cuál es el daño de anular propiedades en Objective-C?

  1. se declara una propiedad con el mismo nombre y el mismo atributo de su superclase. (Ya que si cambia el atributo que puede obtener un compilador aviso) Y usted puede synthesieze con una Ivar que tu creas. ¿Cuál es el uso de esto? ¿O cuál es el daño que puede hacer?

  2. Si una superclase declara una propiedad en una extensión de clase (una categoría sin nombre), entonces podría no ser en el archivo de encabezado. Si no conoce esa propiedad del archivo de encabezado , puede declarar la propiedad del mismo nombre con el atributo any o la clase que desee. Pero el método setter/getter anulará los de esa "propiedad secreta". Creo que esto solo puede hacer daño. Pero ya que no lo sabe desde el archivo de encabezado , ¿cómo puede evitar esto?

  3. Se puede declarar una propiedad en el archivo de cabecera como "sólo lectura" y en la extensión de clase redeclare como "lectura-escritura". Creo que esta es la situación que puede hacer bien.

¿Entiendo esto? ¿No es así? Y no sé qué bien pueden hacer la primera y la segunda situación. Pero si quiero evitar la primera situación, puedo verificar si la subclase ya tiene la propiedad antes de declararla. Pero si la propiedad no está en el archivo de encabezado público, como en la segunda situación, simplemente no sé qué hacer.

Respuesta

5

Hay un lugar adecuado para cada una de las situaciones que usted ha mencionado, con diferentes frecuencia de uso en el medio silvestre. Solo debes tener cuidado de no pisotearte. Ilustraré con ejemplos que personalmente he encontrado.

subclases para anular intencionalmente una propiedad
En esta situación, al igual que Joe mencionó, es mejor que saber exactamente lo que está haciendo y no tienen otras opciones antes de sustituir una propiedad. Personalmente he descubierto que, por lo general, es suficiente anular un único setter o getter para una propiedad ya existente para lograr la personalización, en lugar de volver a declarar y sintetizar la propiedad. Por ejemplo, considere una subclase UIView especializada que solo tiene sentido para tener un fondo UIClearColor. Para hacer cumplir esto, puede anular -setBackgroundColor: para simplemente imprimir un mensaje de advertencia y luego no llamar a la implementación de super. Diré que nunca tuve una razón para anular completamente una propiedad, pero no diré que no podría ser una herramienta útil en algún caso en el que necesite secuestrar por completo una propiedad existente.

propiedad privada
Esto es más útil que usted le da el crédito correspondiente. La alternativa a una propiedad privada es un simple olivar, que todos conocemos. Si se trata de una Ivar que está cambiando con cierta frecuencia, que va a terminar con trozos de código que se ven así:

[_myIvar release], _myIvar = nil; 

o:

[_myIvar release]; 
_myIvar = [someValue retain]; 

Si bien no se ve tan mal, El código repetitivo de administración de memoria como este se pone realmente viejo, muy rápido. Alternativamente, podríamos implementar el ejemplo anterior como una propiedad privada, con retener semántica. Esto significa, no importa qué, sólo tenemos que:

self.myIvar = someValue; 

que es mucho más fácil en los ojos y los dedos después de un rato. Tiene razón al señalar que, dado que esta propiedad es invisible para el resto del universo, podría ser anulada accidentalmente por una subclase. Este es un riesgo inherente al desarrollarse en Objective-C, pero puede tomar medidas para que el riesgo sea infinitamente pequeño. Estas medidas son variaciones en la modificación del nombre de sus propiedades privadas de manera predecible. Hay infinitos caminos que podría tomar aquí: digamos, por ejemplo, establece una política personal para anteponer sus nombres de propiedad privada con sus iniciales y un guión bajo. Para mí, obtendría algo como mw_ivar, y los accesos correspondientes -setMW_ivar: y -mw_ivar. Sí, es estadísticamente posible que alguien pueda venir y anular accidentalmente ese nombre, pero en realidad, no lo harán. Especialmente si tiene una forma de publicar sus prácticas a aquellos que pueden usar su código. Y, puedo decir con seguridad que Apple no ha dado la vuelta y ha hecho propiedades privadas que fueron destrozadas de esa manera, por lo que estarás a salvo en ese frente también.

Públicamente sólo lectura, de lectura y escritura privada
esto es sólo una práctica estándar. Tiene razón en que es útil, y también que no es peligroso ya que la propiedad está en el encabezado. Cualquiera que lo anule accidentalmente solo tiene la culpa.

+0

Otro uso que te falta en esta otra gran respuesta es para especificar un tipo más específico en una subclase. Es decir.usted tiene una propiedad de tipo 'id' en el padre. En la subclase, puede hacer esto más específico redeclarando la propiedad (como un 'NSString *') y luego usando '@dinámica propertyName' en la subclase para informar al compilador que use el almacenamiento en el elemento primario. –

0

Buena pregunta

  1. El uso de este que es como el desarrollador debe saber lo que está haciendo en este punto y necesita agregar personalizaciones a la propiedad de clase base. Y como sabe qué está haciendo, llamará correctamente a la implementación de super a menos que tenga buenas razones para no hacerlo. La decisión no llamada super podría ser dañina especialmente en las situaciones donde no se sabe cómo se implementa la clase base .

  2. Sí Esto es perjudicial, pero se puede evitar no sobre el uso de categorías y eligiendo cuidadosamente un nombre de propiedades o métodos y considerar un prefijo.

  3. Sí, tiene la razón que es buena para que limita el acceso a su propiedad.

Ejemplo para # 2

@interface UIView(PFXextended) 
-(NSArray*)PFXGetSubviewsOfType:(Class)class; 
@end 
Cuestiones relacionadas