2010-03-26 20 views
6
NSString *myString = @"sample string"; 
    NSString *newString = [myString copy]; 

Si configuro un punto de interrupción después de estas dos líneas, el puntero de myString es el mismo que el puntero de newString.NSString copia no copia?

WTF? ¿No se supone que la copia de NSString devuelve un puntero a un nuevo objeto? ¿O me estoy perdiendo algo fundamental sobre cómo se supone que funciona la copia?

+0

No sé la respuesta, pero si cambia mystring entonces tanto tener diferentes direcciones ... hasta que el contenido de la cadena es la misma que está en la misma dirección ... –

+2

Primero, en realidad no llamó a la copia, llamó a stringWithString :. En segundo lugar, dado que las cadenas son inmutables, el compilador y el tiempo de ejecución hacen optimizaciones. Por lo general, los objetos inmutables se devolverán con un recuento de referencia adicional en lugar de crear un objeto nuevo real. –

+0

Beauty of cocoa: no hacer copias de los datos cuando no es necesario ... – stefanB

Respuesta

9

Desde NSString es no mutable que sólo podría aumentar internamente ref count y hacerse con él.

Cuando release uno de esos NSStrings podría decrecer ref count - gestión de memoria estándar.

¿Ve algún problema con eso?

6

Piensa en esto: NSMutableString es una subclase de NSString. Cuando su propiedad se declare como NSString, no espera que cambie.

tener en cuenta, si se ha utilizado retain y alguien le dio una NSMutableString y más tarde no cambiarlo, la clase se romperá.

Sin embargo, puede pensar que siempre copy ing es lento. Entonces NSString 's copy simplemente llama retain. NSMutableString 's copy hace una copia real.

Por lo general, es mejor dar un escupitajo NSString * porque la gente no tendrá que copiarlo todo el tiempo.

1

Es una mejor práctica copiar el valor de cadena devuelto por un método, ya que el valor devuelto puede ser un objeto de cadena mutable, y este valor puede modificarse en otro hilo una vez devuelto por ese método.

1

puede asignar nueva variable al igual que en la muestra

NSString *anotherString = [[NSString alloc] initWithString:originalString];