Pregunta

He escuchado de varias fuentes (stackoverflow.com, cocoa-dev, la documentación, blogs, etc.) que es "incorrecto" usar accesores y configuraciones (foo, setFoo:) en sus métodos init y dealloc.Entiendo que existe una remota posibilidad de confundir a otros objetos que están observando la propiedad si lo hace.(se da un ejemplo simple aquí)

Sin embargo, debo decir que no estoy de acuerdo con esta práctica por el siguiente motivo:

El nuevo tiempo de ejecución de Objective-C (el del iPhone y el de 64 bits en 10.5) le permite declarar propiedades sin declarando un ivar correspondiente.Por ejemplo, la siguiente clase se compilará perfectamente en 10.5 o para iPhone (dispositivo, no simulador):

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

Entendiendo que lo anterior es una clase Objective-C perfectamente válida, digamos que decido escribir un inicializador y, para fines de administración de memoria, un método de asignación (ya que GC no está disponible en el iPhone).Todo lo que he leído sobre inicializadores y desasignación me llevaría a escribir los dos métodos siguientes:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

Sin embargo, según la documentación y la opinión popular, esto es "incorrecto".Entonces mis preguntas son estas:

  1. ¿Cómo se supone que debo inicializar algún objeto sin utilizar el descriptor de acceso?Se podría decir que el compilador (o el tiempo de ejecución o lo que sea) garantizará que algún objeto ya esté configurado en cero, pero creo que sería un comportamiento inadecuado confiar en eso.Al tener una experiencia decente en C, he visto una buena cantidad de errores debido a que las variables no se inicializan correctamente, y esto no parece muy diferente.
  2. ¿Cómo puedo liberar algún objeto si se supone que no debo usar el descriptor de acceso en el método dealloc?

Si la respuesta a cualquiera de estas preguntas es "no puedes", entonces ¿cómo puede ser malo utilizar accesores en tus métodos init y dealloc?

¿Fue útil?

Solución

Yo entiendo que el 10,5 comportamiento actual en virtud del cual los Ivars sintetizados no son accesibles directamente por Apple que se considera ser un error; usted debería ser capaz de acceder directamente a ella, pero no puede.

Por lo tanto, usted debe ser capaz de hacer:

someObject = nil;

en lugar de

self.someObject = nil;

Mientras tanto, utilizando el descriptor de acceso directo es la única manera de hacerlo sin proporcionar una Ivar explícita.

Actualizar : Este error se ha corregido; Ahora usted puede hacer someObject = nil muy bien.

Otros consejos

EDITAR (13 de febrero de 2013): Como señalé en mi comentario a continuación, y especialmente desde la incorporación de ARC, cambié de opinión al respecto.Antes de ARC, vi muchos errores que causaban fallas debido a asignaciones ivar incorrectas en init.En mi opinión, especialmente trabajando con equipos junior, los raros problemas con el uso de accesorios en init fueron superados por los errores comunes de acceso a ivar.Dado que ARC ha eliminado este tipo de errores, los errores raros pero posibles que surgen al usar el descriptor de acceso en init pueden causar son más importantes, por lo que he pasado a apoyar el uso directo de ivars en init y dealloc, y sólo en esos lugares;descriptores de acceso en cualquier otro lugar que sea posible (obviamente no se pueden utilizar descriptores de acceso dentro del propio descriptor de acceso...)


respuesta PRE-ARCO

Estoy totalmente en desacuerdo con quienes se oponen a los accesores en -init.En casi todos los casos, este es un muy buen lugar para usar descriptores de acceso y evita muchos errores que he visto en los nuevos codificadores de Cocoa que invariablemente no logran retener al asignar -init.

-dealloc es una decisión más difícil.Tengo una inclinación natural a usar accesores allí (para que se usen en todas partes), pero puede causar dolores de cabeza debido a KVO (o incluso NSNotifications si publica una notificación de cambio en su configurador).Dicho esto, aunque no uso descriptores de acceso en -dealloc, lo considero muy discutible y Apple es muy inconsistente al respecto (sabemos que están llamando setView: en UIViewController -dealloc por ejemplo).

En cualquier caso, diría que el uso insuficiente de los descriptores de acceso ha causado 100 veces más errores por uso excesivo.Siempre me equivocaría al usarlos, excepto cuando haya una razón de peso para no hacerlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top