2009-11-02 8 views
13

Estoy declarando una propiedad NSString en una clase y Objective-C se queja de que:NSString ningún atributo 'assign', 'mantener', o 'copia' se especifica

NSString no 'Asignar', ' retener ', o' copiar 'atributo está especificado

Luego, casualmente me deja saber que "asignar se utiliza en su lugar".

Puede alguien explicarme la diferencia entre asignar, conservan y copia en términos de normales de gestión de memoria funciones de C?

Respuesta

29

Creo que está llamando su atención sobre el hecho de que se está usando assign, a diferencia de retain o copy. Como un NSString es un objeto, en un entorno contado de referencia (es decir, sin recolección de basura), esto puede ser potencialmente "peligroso" (a menos que sea intencional por diseño).

Sin embargo, la diferencia entre assign, retain y copy son los siguientes:

  • asignar: En el método setter para la propiedad, hay una asignación simple de la variable de instancia para el nuevo valor , por ejemplo:

    - (void)setString:(NSString*)newString 
    { 
        string = newString; 
    } 
    

    Esto puede causar problemas ya que los objetos de Objective-C utilizan recuento de referencias, y por lo tanto al no retener el objeto, existe la posibilidad de que la cadena podría ser desasignada mientras todavía la usas.

  • conservan: este retiene el nuevo valor en el método de selección. Por ejemplo:

    - (void)setString:(NSString*)newString 
    { 
        [newString retain]; 
        [string release]; 
        string = newString; 
    } 
    

    Esto es más seguro, ya que ustedes afirman explícitamente que quiere mantener una referencia del objeto, y hay que liberar antes de que se cancela la asignación.

  • copia: esto hace una copia de la cadena en su método de selección:

    - (void)setString:(NSString*)newString 
    { 
        if(string!=newString) 
        { 
         [string release]; 
         string = [newString copy]; 
        } 
    } 
    

    Esto se utiliza a menudo con cadenas, ya que se hace una copia del objeto original se asegura de que no se cambia mientras lo estás usando

10

Cocoa utiliza el recuento de referencias para administrar la memoria. Los objetos con un recuento de referencia de 0 se eliminan.

  • Asignar - no hace nada para hacer referencia a contar simplemente apunta la variable a los datos
  • retienen - apunta la variable a los datos y añade 1 al contador de referencia, los datos se garantiza que sea allí mientras la variable sigue vivo
  • copia - hace una copia de los datos, señala la variable en ella y hace que la cuenta de retención 1

Más detalles here, en la propia documentación de Apple.

+1

conservar - __a incluso si__ alguien [deallocs] el NSString al que está haciendo referencia? ¿O solo funciona si todos los usuarios de esa misma instancia [lanzan]? – bobobobo

+1

@bobobobo - usted debe * nunca * llamar 'dealloc' usted mismo. Deberías * siempre * usar 'release' o' autorelease'. –

+0

Lo que dijo Dave. La razón por la cual sus datos están garantizados es porque usted supone que todos los demás solo utilizan la versión, lo que reduce el recuento de referencias solo por su referencia. Si otras personas, o usted mismo, aprueban el dealloc o liberan un objeto (por lo tanto, no siguen las reglas) ¡sus datos no están garantizados! – bmalicoat

3

assign - el ivar se establece mediante una simple asignación. Implementación:

- (void) setFoo:(NSString *)newFoo { 
    foo = newFoo; 
} 

retain - el Ivar se envía el mensaje de retener antes de hacer la tarea. Implementación:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo retain]; 
    } 
} 

copy - el Ivar se envía el mensaje de copia antes de hacer la asignación. Implementación:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo copy]; 
    } 
} 
+1

Estas no son las implementaciones reales que el compilador @synthesizes, pero demuestran el comportamiento desde una perspectiva de administración de memoria (que no es de GC). –

+0

@Nikolai - sí, gracias por aclarar. –

Cuestiones relacionadas