2011-06-21 16 views
5

En el ejemplo siguiente, no entiendo por qué localVariable se está accediendo por valor en doSomethingWithObject. ¿Qué hace esa conversión? ¿Cómo distingue entre acceder a una variable por valor y acceder a ella por referencia? Me gustaría ver más ejemplos relacionados si es posible.Acceso a las variables por valor o referencia

El siguiente es un extracto de Blocks Programming Topics de Apple y muestra cómo las variables de instancia se conservan en bloques.

Si utiliza un bloque dentro del implementación de un método, las reglas para la gestión de memoria del objeto variables de instancia son más sutiles:

  • Si accede a una variable de instancia por referencia, self Es retenido;
  • Si accede a una variable de instancia por valor, la variable se conserva.

Los siguientes ejemplos ilustran las dos situaciones diferentes:

dispatch_async(queue, ^{ 
    // instanceVariable is used by reference, self is retained 
    doSomethingWithObject(instanceVariable); 
}); 

id localVariable = instanceVariable; 
dispatch_async(queue, ^{ 
    // localVariable is used by value, localVariable is retained (not self) 
    doSomethingWithObject(localVariable); 
}); 

Respuesta

12

Es porque cuando se accede a una variable de instancia directamente, el compilador (más o menos) se traduce esto en una búsqueda de miembro de estructura. Por lo tanto:

[ivar doSomething]; 

Se convierte en

[self->ivar doSomething]; 

Debido self que se necesita, self debe ser retenido. Sin embargo, cuando copia el valor del puntero en una nueva variable, ya sabe que necesita la estructura self para saber cuál es el valor del puntero y, por lo tanto, no es necesario retener self, porque el valor del puntero puede ser const copiado de la pila. Eso no puede suceder con una variable de instancia (porque el ivar podría cambiar entre cuando se crea el bloque y cuando se ejecuta el bloque).


Aclaración:

  • un bloque debe conservar todos los objetos de los que hace referencia interna para asegurar que esos objetos seguirán existiendo durante la vida útil del bloque.
  • cuando accedes a un ivar directamente en el código, en realidad estás buscando un miembro de una estructura (ya que los objetos Objective-C realmente son solo estructuras)
  • buscando un miembro de una estructura significa que tienes que tener la estructura
  • por lo tanto, un bloque retendrá la estructura (en este caso, self) para que la búsqueda siempre tenga éxito. Si no hiciera esto, entonces self podría ser desasignado en el futuro, y ahora la búsqueda de estructura causaría un mal acceso (lo más probable) y su aplicación fallaría.
  • Como alternativa, podría crear un nuevo puntero de objeto localmente en el marco de pila actual.La ventaja de esto es que usted ya no tiene que retener self, porque self ya no está involucrado en la recuperación de la dirección del objeto en cuestión
  • por supuesto, será retenido el objeto referenciado por la variable local para asegurarse de que existe durante toda la vida del bloque.
  • usando los términos "por valor" y "por referencia" aquí es completamente incorrecto. Los objetos en Objective-C siempre se pasan por referencia, ya que siempre están pasando punteros. Usted no puede pasar un objeto por valor en Objective-C. (Hay algunas advertencias a esto, pero realmente no quieren ir allí) Para obtener más información sobre lo que significa pasar algo de valor frente por referencia, echa un vistazo a esta pregunta: What's the difference between passing by reference vs. passing by value?
+0

No estoy seguro de entender perfectamente esto ... pero gracias por la explicación de todos modos. – Pablo

+0

@Dave, no el mío. Sin embargo, no puedo conectar la última oración con el resto de tu explicación. "Eso" implica ¿a qué? Tampoco puede obtener la parte de const copy. Por lo que puedo entender simplemente es que si puedes sustituir ivar con self-> ivar, entonces self se conserva, si no se puede, entonces se conserva ivar. Pero lo que es 'por valor',' por ref' todavía no está claro para mí. Lo siento. – Pablo

+0

@Michael respuesta actualizada –

Cuestiones relacionadas