2009-05-25 11 views
8

He leído en varios libros ... y en línea ... sobre cadenas inmutables y mutables. Ellos afirman que "cadenas inmutables" no se pueden cambiar. (Pero nunca definen "cambio").La última palabra en NSStrings: mutable e inmutable

¿Cuáles de estos NSStrings podrían cambiarse sin utilizar NSMutableString?

La cadena contiene "bagre" ... y luego trato de cambiarlo a "gato". (Mismas letras, solo más corta)

Contiene "gato" ... y trato de cambiarlo por "bagre". (Inicio similar ... pero acaba de hacer más.)

Cambio "cat" en "CAT". (Mismas letras, pero solo el caso ha cambiado)

Cambio "cat" en "perro". (Cadena totalmente diferente, pero con la misma longitud)

Cambio "cat" en "dogwood". (Cadena totalmente diferente, pero más larga)

+0

¡Casi una pregunta clintoniana! –

Respuesta

20

La respuesta es - ninguna. Inmutable significa que no se puede cambiar a cualquier cosa diferente de la cadena original. Cada personaje permanece igual, la duración no puede cambiar, etc. Una vez que se define, no se puede cambiar nada de esa cadena. Si desea hacer que sea más largo o más corto o cambiar cualquiera de los caracteres, debe crear una nueva cadena (o usar un NSMutableString para comenzar).

+0

Gracias por la respuesta rápida. ¿Eso no hace que NSString sea bastante inútil? Configuré * VARIABLE * en un valor NSString ... y luego nunca puedo cambiarlo. ¿No es comúnmente llamado "constante" en otros idiomas? Preferiría (en cambio) querer "hacer algo" con mis picaduras el 99% del tiempo. Entonces, ¿no debería usar MSMutableString en casi todos lados? (Pero rara vez lo veo usado, comparado con el NSString MUY comúnmente usado.) – Donna

+0

Imagine si int/float/long también son inmutables. int x = 5; y luego x puede * NUNCA * cambiarse. Inmutable es (casi) inútil. ¿No? – Donna

+0

"hacer algo" podría simplemente implicar leerlos en algún almacén de datos y mostrarlos. En este caso, no querrá modificarlos. – rein

2

es necesario definir el "cambio", también :)

Básicamente, cuando se crea un NSString, que está creando una matriz de caracteres y que está diciendo al compilador que el contenido de dicha matriz nunca cambiará La parte "nunca cambiar" es la parte "inmutable"; los datos que contiene la cadena no pueden ser modificados.

Por otro lado, un NSMutableString le permite realmente cambiar los datos a los que apunta (de ahí que sea 'mutable'). Tenga en cuenta el método 'appendString' que existe para NSMutableString; esto realmente toma datos y los golpea al final de la cadena.

Por ejemplo, si usted tenía:

NSString * miCadena = @ "gato"; myString = @ "Goldfish";

Eso funcionaría bien. En realidad, nunca está cambiando los datos que myString contiene; simplemente le está diciendo que quiere que apunte a un nuevo segmento de datos inalterables.

La única ocasión en la que tendría problemas con las diferencias entre objetos intercambiables e inmutables es si intentó modificar myString directamente (por ejemplo, agregar "s son geniales" a él o algo así).

En otras palabras, cualquier clase le permitiría "cambiar" cualquier cadena en cualquier otra cadena, pero los métodos que utilizó para hacerlo serían muy diferentes. Por ejemplo, para convertir "cat" en "CAT" con una cadena mutable, podría iterar sobre cada carácter y simplemente hacer que sea mayúscula (ya que puede modificar el contenido de una cadena mutable). Con una cadena inmutable, por otro lado, primero tendría que copiar la cadena original en otro lugar, modificarla y luego redirigir su variable para apuntar a este nuevo NSString.

Los siguientes enlaces pueden ser útiles: http://www.kirupa.com/forum/showthread.php?t=307928 http://forums.macrumors.com/showthread.php?t=467099

También recomiendo hacer algunas google; esta es una pregunta que se relaciona con el desarrollo en general, y es un concepto relativamente importante de entender. También se ha discutido hasta la muerte en otro lugar en Internet.

+0

¿Sería "más seguro" y "más flexible" usar simplemente NSMutableString en todas partes? Dicen que hay un "costo de memoria" y un "costo de velocidad" ... pero ... ¿cuánto? 20 bytes adicionales de mi grupo de millones? ¿O ralentizando mi aplicación por 0.01 segundos? (Los beneficios de "nunca tener que preocuparse por los mutables" parecen valer la pena). ¿O es así? – Donna

+1

Si está utilizando la programación concurrente (múltiples hilos, etc.) es muy bueno saber que el contenido de su cadena no cambiará en el medio de su uso de la misma. Si tuviera que preocuparse por eso, probablemente haría una copia de la cadena antes de hacer cualquier otra cosa para que nadie la cambie. La inmutabilidad lo hace para que no tenga que copiar la cadena. Esto se vuelve aún más importante para estructuras más grandes como NSArray y NSDictionary. Si solo tienes un hilo (si no sabes lo que eso significa, solo tienes uno), usar mutables en todos lados probablemente sea perfecto. –

+0

Incluso si no está utilizando más de un hilo, es bueno saber si un objeto puede cambiar debajo de usted. En general, me resulta más sencillo utilizar las estructuras de datos inmutables la mayor parte del tiempo. Si creo un NSArray, se lo doy a otra persona y luego continúo usándolo, es útil saber si alguien lo ha cambiado a mis espaldas. En resumen, usar mutable en todas partes es más fácil de escribir, pero mucho más difícil de depurar. – rpetrich

11

Si declaro una variable:

NSString * var; 
// Here some code giving a new value to var 

lo que es inmutable es el objeto apuntado por var, no var sí.

Esto significa que no puedo cambiar nada del objeto apuntado por var, pero puedo cambiar a qué objeto se apunta.

Ninguna de las operaciones que mencionas está permitido en var, pero puede asignar var con otra cadena diferente:

NSString * anotherVar; 
// Here some code giving a new value to anotherVar 

var = anotherVar; // This is allowed (with a memory leak if GC is disabled) 

// The following is also allowed: -stringWithFormat: creates a new object 
var = [var stringWithFormat:@"%@ with more chars", var]; 
+0

Solo para tener en cuenta, ese código * no * debería dar como resultado una pérdida de memoria con GC desactivado. Lo que estás haciendo es una asignación simple, sin la participación de ninguna retención o copia. Por lo tanto, no hay pérdida de memoria. Además, su formato de cadena debe ser @ "% @ con más caracteres", ya que% s solo aplica para C-Strings, creo. –

+0

Gracias, he actualizado el formato. Acerca de la pérdida de memoria, depende de cómo se haya creado el primer valor de var. – mouviciel

2

Una cadena inmutable (o, de hecho, cualquier objeto inmutable) es uno que no puede ser cambiado en absoluto después de la inicialización.

Ésta es la ventaja de usar cadenas inmutables, en la (pseudo) pseudo-código:

// if using mutable strings 
let a = "Hello World"; 
let b = a; 
a.replace("Hello", "Goodbye"); 

Ahora lo que hace un asimiento? "Hola Mundo"? "Adiós mundo"? Ahora, ¿qué contiene b?

Si las cadenas son mutables, entonces podría contener "Goodbye World". Esto puede ser lo que quieres. Puede que no sea

Con la inmutabilidad, queda muy claro que b aún apunta a la cadena original, porque el método de reemplazo no puede haber cambiado la cadena real, sino que más bien devolvió una referencia a una nueva cadena.

Es posible que no vea mucho beneficio en este ejemplo. Pero si a y b son referenciados y utilizados en diferentes partes del código, o en diferentes hilos, tener referencias inmutables elimina muchos errores potenciales.

3

NSString no se puede editar, cada vez que asigne un valor de cadena al objeto NSString huérfano el antiguo objeto de cadena y volver a crear el nuevo objeto de cadena. Esa es una operación costosa si se trata de un buffer de cadena grande. Si está trabajando con un búfer de cadena grande, utilice NSMutableString para obtener un rendimiento óptimo. Esto es similar a string vs stringBuilder en .net.

1

De forma predeterminada, NSString utilizado en el lenguaje objetivo C es inmutable. NSMutableString se utiliza para declarar & definir una cadena mutable. No se puede cambiar nada en una cuerda inmutable. No la longitud, ni los personajes, nada.

Cuestiones relacionadas