2010-09-27 12 views
5

Cada vez que necesito crear una nueva variable NSString siempre lo asigno e inicio. Parece que hay momentos en los que no quieres hacer esto. ¿Cómo sabe cuándo asignar e iniciar un NSString y cuándo no?Cuándo no asignar e iniciar un NSString

+1

Su pregunta tiene poco sentido. Muéstranos algunos ejemplos. –

+6

Crear una nueva 'NSString' a través de' [[NSString alloc] init]; 'es una de las cosas más inútiles que podrías hacer en Cocoa. La cadena resultante es inmutable y vacía. –

Respuesta

18

Whenever I need to create a new NSString variable I always alloc and init it.

No, eso no tiene sentido.

La variable de existe desde el momento en que el programa llega al punto donde se declara:

NSString *myString; 

Esta variable no es un NSString. Es el almacenamiento de un puntero a un NSString. Eso es lo que indica *: que esta variable contiene un puntero.

Existe la NSString objeto sólo desde el momento en que crear una:

[[NSString alloc] init]; 

y el puntero a ese objeto es sólo en la variable desde el momento en que se le asigna allí:

myString = [[NSString alloc] init]; 
//Or, initializing the variable in its declaration: 
NSString *myString = [[NSString alloc] init]; 

Por lo tanto, si va a obtener un objeto de cadena desde otro lugar (p. Ej., substringWithRange:), puede omitir la creación de uno nuevo, vacío, porque simplemente va a reemplazar el puntero a la cadena vacía con el puntero al otro.

Algunas veces desea crear una cadena vacía; por ejemplo, si va a obtener un grupo de cadenas de a una por vez (por ejemplo, de un NSScanner) y desea concatenar algunas o todas en una cadena grande, puede crear una cadena mutable vacía (usando alloc y init) y enviarlo appendString: mensajes para hacer las concatenaciones.

También necesita release cualquier objeto que cree por alloc. Esta es una de las reglas en el Memory Management Programming Guide.

+0

Recordatorio: Ignore la parte sobre 'lanzamiento' cuando construya su aplicación en [ARC] (http://en.wikipedia.org/wiki/Automatic_Reference_Counting).Además, si desea autoejecutar una instancia de una cadena vacía (en oposición al puntero nulo descrito en esta respuesta), use este método de clase de conveniencia: 'NSString * myString = [cadena NSString];' –

+0

@BasilBourque: aún más idiomático sería '@" "', aunque no se garantiza que sea una nueva cadena (aunque tampoco lo es '[[NSString alloc] init]', que puede devolver una cadena constante). –

+0

'[NSString string]' parece más autodocumentado, ya que esto significa absolutamente "Quiero una cadena vacía no nula". '@" "' tiene alguna ambigüedad: ¿el autor simplemente se olvidó de completar el literal de la cadena prevista? (He visto que eso sucede cuando la indecisión se cierne sobre la elección de la redacción exacta.) Por otro lado, si de hecho es posible que pueda cambiar esto en el futuro para que no esté vacío con algún tipo de texto, utilice '@" " 'en primer lugar. –

12

Si desea inicializar a un valor conocido, no tiene mucho sentido en el uso de alloc, sólo puede utilizar una cadena literal:

NSString* myStr = @"Some value"; 

Si desea inicializar con un formato o lo que sea, pero no lo necesitan para quedarse más allá de la actual vida útil de la piscina autorelease, que es un poco más ordenado a utilizar los métodos de conveniencia clase:

NSString* myTempStr = [NSString stringWithFormat:@"%d", myIntVar]; 

Si necesita su tiempo de vida para ir más allá de eso, ya sea alloc/init o bien agregue un retain a la llamada anterior. Tiendo a preferir ligeramente este último, pero los dos son bastante equivalentes. De cualquier manera, necesitará un balanceo release más tarde.

Tenga en cuenta que, dado que NSString no es mutable, este tipo de cosas no sólo es innecesario, sino activamente mal:

// don't do this! 
NSString* myStr = [[NSString alloc] initWithString:@""]; 
myStr = someOtherStr; 

ya que se escapa el valor inicial del marcador de posición.

+0

¿Cómo sabes cuál es el tiempo de vida del conjunto de autorrelease actual? –

+0

@awakeFromNib Al leer la [sección correspondiente] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html) de los documentos de gestión de memoria. Comúnmente se puede pensar que un objeto liberado automáticamente dura hasta que lo pierdas de vista, y luego solo un poco más (es decir, lo suficiente como para ser un valor válido de devolución). Si está creando cosas en un bucle, es posible que desee administrar un grupo de autorrelease para evitar acumular una gran cantidad de asignaciones inéditas, pero el valor predeterminado debería estar bien para un puñado de cadenas durante el manejo de eventos. – walkytalky

+0

Esto es quisquilloso, pero el valor del marcador de posición @ "" no se filtra: ocupa espacio en el binario de la aplicación, por lo que no hay nada que liberar. Es un poco derrochador, pero no estás perdiendo memoria ... –

1

Supongo que se está refiriendo a usar StringWithString o similar en lugar de initWithString? StringWithString alloc y inits para usted debajo del capó y luego regresa una cadena autorrellenada.

Si no necesita hacer ninguna otra manipulación de cadenas que tener la cadena, puede utilizar NSString *str = @"string";

En general con IOS, más apretado a administrar su memoria el mejor. Esto significa que si no necesita devolver una cadena desde un método, debe asignar init y luego liberarlo.

Si necesita devolver una cadena, por supuesto tendrá que devolver una cadena autorrellenada. No creo que sea más complicado que eso.

+0

No. Él se está refiriendo a esto: http://stackoverflow.com/questions/3796312/why-doesnt-this-code-produce-the-correct-output/3796955#3796955 –

4

It seems that there are times when you don't want to do this.

No puedo pensar en ningún momento en el que me gustaría desee alloc/init un NSString. Desde NSStringgs son inmutables, que casi siempre crea nuevas cadenas por uno de:

  • conveniencia método de clase, por ejemplo,

    NSString* foo = [NSString stringWithFormat:...]; 
    
  • literal

    NSString* foo = @"literal"; 
    
  • NSString método de instancia

    NSString* foo = [bar uppercaseString]; 
    
  • copia de cadena mutable

    NSString* foo = [mutableBar copy]; // foo needs to be released or autoreleased in this case 
    
+0

Es posible que desee leer un archivo y guardarlo en una variable de instancia, en cuyo caso usaría 'initWithContentsOfFile: encoding: error:'. (O 'stringWith ...' and 'retain', pero eso no es más eficiente para usted o para el programa.) –

+0

@Peter Hosey: Usaría el método de clase de conveniencia en ese caso. – JeremyP

Cuestiones relacionadas