2011-02-03 18 views
5

¿Alguien puede explicar la diferencia entre la configuración someObject = someOtherObject; y self.someObject = someOtherObject; si algún Objeto es una propiedad de clase creada con @property (no atómico, retener) SomeType someObject;Cuándo acceder a la propiedad consigo mismo y cuándo no?

Para aclarar Tengo algo como:

@interface SomeClass : NSObject { 
    SomeType* someObject; 
} 

@property (nonatomic, retain) SomeType* someObject; 

@end 

he notado a veces me ACCESO EXC_BAD cuando se utiliza la propiedad sin auto y parece bastante al azar. Cuando uso self, mi programa actúa como debería ser. No recibo ningún error o advertencia del compilador cuando me salteo, así que supongo que es de alguna manera una sintaxis válida.

+0

Posible duplicado de [¿cuándo debería usar la palabra clave self.] (Http://stackoverflow.com/questions/4080523/when-should-i-use-the-self-keyword) Esto se pregunta con mucha frecuencia, no ¿buscas antes de hacer la pregunta? – zoul

Respuesta

2

Las propiedades son solo una forma conveniente de acceder a los datos. Por lo tanto, cuando declare la propiedad @property (no atómica, retenga) SomeType * someObject; esto significa que durante el acceso no habría sintetizarse 2 métodos:

getter:

-(SomeType*) someObject { 
    return someObject; 
} 

setter

-(void) setSomeObject:(SomeType*) obj { 
    [someObject release]; 
    someObject = [obj retain]; 
} 

Así que la principal diferencia entre las propiedades y ivars es que las propiedades crear dinámicamente el setter/getter métodos (y puedes anularlos). Pero cuando estás escribiendo algún objeto = new_val, solo estás copiando la referencia a la ubicación de la memoria. No se realiza ningún trabajo adicional allí excepto una instrucción de ensamblaje.

Hay una cosa más para mencionar: atómica y no atómica. Con atomic, el setter/getter sintetizado asegurará que siempre se devuelva un valor completo desde el getter o que establezca el setter, independientemente de la actividad del setter en cualquier otro thread. Es decir, si el hilo A está en el medio del captador mientras el hilo B llama al colocador, un valor viable real, un objeto liberado automáticamente, será devuelto al llamante en A.

En no atómico, no se hacen tales garantías. Por lo tanto, no atómico es considerablemente más rápido que atómico.

Editar: por lo tanto, si tiene alguna variable, a la que se accede desde diferentes hilos o/y se debe realizar algún trabajo adicional (por ejemplo, retener, levantar algunos indicadores ...), entonces su elección es propiedad. Pero a veces tiene una variable a la que se accede con mucha frecuencia y el acceso a través de la propiedad puede generar una gran sobrecarga, ya que el procesador debe realizar muchas más operaciones para sintetizar y llamar al método.

4

self.someObject = someOtherObject hace uso de la propiedad. Las propiedades generan setters y getters para ti. En su caso, usted otorgó el atributo retain a la propiedad, lo que significa que un objeto establecido a través de esta propiedad recibirá automáticamente un mensaje retain que aumenta su recuento de retención en 1. Además, el antiguo valor de la variable miembro recibe un mensaje release que disminuye su conteo de retención.

Obeques que se desasignan, cuando su recuento de retención llega a 0. Obtiene una EXC_BAD_ACCESS ecxeption si intenta acceder a un objeto desasignado (por ejemplo, si intenta liberarlo con demasiada frecuencia).

En su caso:

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1 
self.someObject = soo; //soo's retain count is now 2 
[soo release]; //soo's retain count is 1 again, as self still uses it. 
[self doSomethingWithSoo]; 

Sin embargo, si usted no utiliza el organismo, no debe liberar soo.

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1 
someObject = soo; //soo's retain count is still 1 
[soo release]; //soo's retain count is 0, it will be deallocated 
[self doSomethingWithSoo]; //will fail with an EXC_BAD_ACCESS exception, as soo does not exist anymore. 
0

La diferencia entre los dos es:

1) cuando no se utiliza "auto". está asignando el resultado directamente a la variable miembro.

2) cuando está utilizando "self". estás llamando al método setter en esa propiedad. Es lo mismo que [self setMyObject: ...];

por lo que en el caso de self.myobject, mantiene su retención, y en otro caso, (sin auto), si no está utilizando alloc, entonces se tratará como objeto liberado automáticamente.

En la mayoría de los casos, encontrará que desea utilizar "self.", Excepto durante la inicialización del objeto.

Por cierto, también se puede utilizar para aumentar self.someObject = [someOtherObject retain] retener contador

1

Se trata de la gestión de memoria.

Su propiedad de clase someObject ha generado accesos con la anotación @property/@synthsize en sus archivos .h/.m.

Al acceder a su propiedad con someObject, tiene acceso directo a la propiedad. Cuando está accediendo al self.someObject está llamando a su accesor [self someObject] que se encarga de la administración de la memoria por usted.

Por lo tanto, cuando necesite asignar una propiedad de clase, es más limpio hacer self.someObject = someOtherObject; porque usa el colocador y no tiene que preocuparse por soltar y retener. Cuando su incubadora se genera con @property (nonatomic, retain), se encargará de retenerla por usted.

Cuestiones relacionadas