2010-07-18 12 views
6

Estoy recogiendo ObjC y Cocoa, que es también mi primera incursión seria en la programación en general.InitWith Methods vs. Factory Methods

Tengo problemas con las diferencias entre los métodos initWith, que se llaman en las instancias, y los métodos de fábrica, que son llamados en las clases.

En primer lugar, ¿por qué se llaman métodos de "fábrica" ​​y existe un término adecuado para lo que he denominado métodos "InitWith"?

En segundo lugar, ¿cuál es la diferencia funcional? ¿Son solo las implicaciones de administración de memoria (que los métodos de fábrica devuelven un objeto liberado automáticamente)?

Por ejemplo, ¿cuál es la diferencia real entre [NSString stringWithString: (NSString*)aString] y [[NSString alloc] initWithString: (NSString*)aString]?

Respuesta

5

La diferencia entre los métodos se describe en Cocoa's object ownership policy. Usted posee el objeto devuelto por -initWithString: y debe liberarlo, pero no posee el objeto devuelto desde + stringWithString y, por lo tanto, no necesita liberarlo (además, si desea hacerse dueño de él, debe retenerlo).

Los métodos de fábrica se llaman así porque devuelven un objeto ya creado para usted, generalmente con los parámetros que usted proporciona que se utilizan para configurar el objeto, para la conveniencia del programador.

0

En el ejemplo de

[[NSString alloc] initwithString: (NSString  
*)aString]; 

Al hacer un alloc va a colocar un espacio para la cadena en la memoria de ahí el alloc. luego dígale que inicialice con la cadena igual a aString. el (NSString *) es un identificador para el tipo de objeto por lo que le está diciendo que aString se declara como un NSString.

por lo general hacer algo como

NSString * aString = @"String value"; 

declara lo que es igual a laCadena.

Si alloc algo en la memoria con el fin de administrarlo tendrá que liberarlo en el momento correcto, tales como la sección

-(void) dealloc {} 

de su código

Todo sobre NSString se puede explicar en esta documentación de Apple NSString

+0

Esto va para los dos, Rugluds y Audacitor: no es necesario que incluya '(NSString *)' al enviar el mensaje 'initWithString:'. Solo la declaración del método lo necesita (para especificar qué tipo espera el método). Cuando lo incluye como parte de un mensaje, está convirtiendo el valor 'aString' en' NSString * '.Si 'aString' es un' NSString * ', entonces esto no hace nada y es innecesario; si es otra cosa, el reparto todavía no hará nada útil: cerrará el compilador, pero se bloqueará en el tiempo de ejecución. –

0

La diferencia principal es que

[NSString stringWithString: 
    (NSString*)aString] 

devuelve una cadena autoreleased cuya gestión de memoria que no es necesario preocuparse, mientras que

[[NSString alloc] initWithString: 
    (NSString*)aString] 

devuelve una cadena que usted es responsable de la liberación. Básicamente, el primero es un atajo para el último, más liberación automática.

+1

bueno, "cuya gestión de memoria no necesita preocuparse" no es toda la historia y podría llevar a un recién llegado por mal camino ... Por ejemplo, si está asignando el resultado a una variable de instancia (1), entonces ' Deseo conservar el resultado de un método de clase o encontrará que cuando acceda a su instancia var se irá. Este es un error clásico para los nuevos en ObjC/Cocoa. (1) una variable de instancia que no es una propiedad con setter sintetizado está configurada para retener a través de los atributos de propiedad. – Dad

+1

Otro error común es confundir variables de instancia con propiedades. La política de gestión de memoria (por ejemplo, 'retener') que declara para una propiedad no tiene ningún efecto en la variable de instancia; las asignaciones a la variable de instancia siempre ocurren sin efectos secundarios, incluidas las retenciones o copias. Por lo tanto, al asignar a un ivar, necesita retener o copiar el valor usted mismo. Solo asignar a una propiedad puede hacer eso por usted. –