23

Pregunta rápida ... Bueno, entiendo que todas las propiedades comienzan como nulas en Objective-C y que enviar un mensaje a nil no hace nada, por lo tanto debe inicializar usando [[Class alloc ] en eso]; antes de enviar un mensaje a una propiedad recién creada. Sin embargo, ¿qué pasa si no estoy enviando mensajes a esta propiedad o si configuro la propiedad usando self.property = something? ¿Tengo que asignar init en estos casos también? Además, ¿las propiedades de la interfaz de usuario también comienzan como nulas, como una propiedad UILabel que arrastra desde su guión gráfico? ¿Estos necesitan alloc init?Ejemplificación lenta en desarrollo de Objective-C/iPhone

Gracias a todos los que responden

+1

+1 muy buena pregunta. Enviar mensajes a la propiedad no-alloc/init es un error común para los principiantes de OjbC. – Philip007

Respuesta

2

La realidad es cuando haces self.myProperty = [[Class alloc] init], usted no está inicializando su propiedad. Por el contrario, está inicializando un objeto que le dice a su propiedad (que de hecho es un puntero) para señalar. Entonces, si ya tiene un objeto asignado e inicializado, no tiene que volver a asignar/init y puede hacer self.myProperty = object;

Las propiedades de la IU no comienzan como cero, esto se debe a que cuando agrega elementos en el constructor de interfaz, la vista posee los elementos que agrega y estos objetos se inicializan automáticamente. Esto significa que si está creando IBOutlets y conectándolos a algunas propiedades, no tiene que alloc/init.

Espero que haya sido útil.

0

No, no es necesario que [[Class alloc] init las propiedades en su método init.

Sin embargo, le recomiendo que los configure explícitamente en Nil en su método init para mayor claridad.

1

No tengo experiencia con Storyboards, pero sé que cuando crea objetos a través de un archivo xib todos los objetos se instancian correctamente cuando le dice a un controlador de vista que use un archivo xib. Por lo tanto, no tiene que preocuparse por asignar/insertar esos objetos en el código.

En cuanto al uso de self.property = <something>, depende de lo que something es. Si algo es cualquier clase de objeto existente, no es necesario realizar el alloc init en ese objeto, ya que la sintaxis self.property = ... llama al método setter de la propiedad que retendrá, copiará, asignará, etc., el nuevo valor a la propiedad de forma apropiada.

Ahora cualquier tipo de objeto existente puede ser un objeto alloc/init'ed, o un objeto liberado automáticamente obtenido a partir de un método de conveniencia (stringWithFormat de NSString, por ejemplo).

Como señaló Kaan Dedeoglu, la sintaxis self.property = ... apunta (y retiene) el ivar al objeto en la memoria, y le corresponde a usted inicializar ese objeto si no está ya instanciado.

34

Stunner hizo un buen trabajo al explicar que no es necesario asignar objetos init que ya se han creado.

Pero si es un objeto que no existe, ¿dónde vas a crearlo? Un patrón muy común, que menciono porque lo mencionaste en tu publicación, es la instanciación lenta.

Así que quiere una propiedad NSMutableArray. Podría asignarlo en algún método antes de usarlo, pero luego debe preocuparse por "¿se llama ese método antes de necesitar mi matriz?" o "voy a llamarlo de nuevo accidentalmente y volver a inicializarlo".

Así que un lugar seguro para hacerlo está en el comprador de la propiedad. Se llama cada vez que accede a la propiedad.

.h 
@property (nonatomic, strong) NSMutableArray* myArray; 

.m 
@synthesize myArray = _myArray; 

- (NSMutableArray*)myArray 
{ 
    if (!_myArray) { 
     _myArray = [[NSMutableArray alloc] initWithCapacity:2]; 
    } 
    return _myArray; 
} 

Cada vez que acceda a esa propiedad, que dice: "¿El miMatriz existir? Si no es así, crear. Si no lo hace, simplemente devolver lo que tengo."

Más un beneficio adicional con este patrón de diseño es que no está creando recursos hasta que los necesita, en lugar de crearlos todos de una vez, por ejemplo, cuando su controlador de vista carga o su aplicación se inicia, lo cual, dependiendo de los requisitos, podría tomar un par de segundos.

+4

Buena respuesta, pero estoy en desacuerdo con la creación de instancias de ivars en getters ya que eso hace inviable la consulta de la existencia del objeto. Más bien, le recomendaría que realice la creación de instancias en el colocador porque sabe con certeza si ese ivar que está configurando no existe, quiere que exista para que se pueda establecer en un valor. Por lo tanto, nunca habrá un momento en el que no desee que exista cuando llame a un setter, mientras que cuando llama a un getter, ese no es siempre el caso. – Stunner

+0

Si puedo agregar algo tan tarde ... ¿necesitaría agregarlo en el setter si la propiedad tiene el atributo 'copiar' ya que ya tendría una copia para usar? – ScottyB