2012-01-28 10 views
6

Tengo la clase A con una variable de instancia ImageView. Actualmente utilizo setTag() para volver de ImageView a la instancia de Clase A. ¿Podría eso presentar un bucle circular? También escuché hablar de referencias débiles. ¿Cuál es la mejor manera de llegar a la clase A padre de ImageView?lleve un registro de la clase principal de la vista de imagen del miembro

Mi escenario de uso es que estoy arrastrando el ImageView alrededor de la pantalla y necesito acceder a la clase A para obtener información acerca del ImageView que se está arrastrando.

+0

¿Por qué no jusr usa su propio HashSet para rastrear sus referencias (ID de ImageView -> instancia de ClassA) ? – Olegas

Respuesta

3

Creo que Dalvik VM no tiene problemas para detectar referencias circulares.

Aquí es Q/A que trata sobre esto: Circular References in Java

Sólo una implementación muy ingenua tendría un problema con circulares referencias.

Utilizaría setTag para mantener la referencia al objeto relacionado. Además, usar setTag/getTag en View es un enfoque estándar y recomendado para lograr diversas optimizaciones en Android, incluso en muestras de Android. Algunas referencias:

http://www.vogella.de/articles/AndroidListView/article.html#ownadapter_viewHolder

Android Custom Listview

Si GC de Android tendría problema para detectar dichas dependencias, Android no funcionaría, ya que funciona. Siga adelante y use View.setTag si le conviene.

+0

estaba buscando confirmación en la web que settag es una referencia débil. parece que no puede encontrarlo? – prostock

+0

Estudie el código fuente de Ver: protegido Objeto mTag; public void setTag (etiqueta de objeto final) { mTag = tag; } –

+0

setTag no tiene nada que ver con WeakReferences. Sin embargo, podría poner una WeakReference en la etiqueta si eso es lo que está tratando de lograr. Una vez dicho esto, asegúrese de entender qué es lo que realmente le proporciona una WeakReference. –

0

La mejor manera de deshacerse de las referencias circulares es hacer que la variable de instancia en A una variable definitiva:

private final ImageView myImageView; 

Esto le obligará a inicializar la variable en el constructor de A. Si se pasa de forma explícita la referencia a ImageView en las nuevas llamadas, evitará las posibilidades de referencias circulares.

public A(ImageView iv, ...) { 
    this.myImageView = iv; 
    ... 
    // associate this instance of A with ImageView? 
    this.imageView.setTag(this); 
    ... 
    } 
1

Las referencias circulares en java no son un problema para el GC. Esto no es un problema debido a un concepto llamado "alcanzabilidad".

Puede pensar en referencias de objeto como un gráfico dirigido, donde los nodos son objetos y los bordes son referencias de objetos. Hay un conjunto de nodos en el gráfico llamado "nodos raíz": estos son (más o menos) los objetos a los que se puede acceder directamente a algún subproceso en la vm. Cosas como variables locales en cualquier función invocar en la pila, campos estáticos en clases, etc.

Al realizar una recolección de elementos no utilizados, la máquina virtual comienza con estos nodos raíz y los marca como "en uso". Luego, para cada borde que sale de estos nodos en uso (es decir, para cada objeto al que se hace referencia desde los objetos en uso), también se marca como en uso, y así sucesivamente, hasta que ya no quede nada. marca. Y luego, cualquier objeto que no haya sido marcado como "en uso", sabe que puede recolectar basura de forma segura.

Ahora, vamos a decir, por ejemplo, estás en algún método, y tiene el siguiente código:

a = new A(); 
a.b = b; 

b = new B(); 
b.a = a 

Ahora tiene una referencia circular entre ay b. Y ambos objetos forman parte del conjunto raíz, porque son una variable local en una llamada a método que está en la pila.

Luego, cuando salga de ese método, tanto a como b ya no formarán parte del conjunto raíz. Y siempre y cuando no hayas hecho referencia a ellos en otro lugar, no hay nada más que contenga una referencia a a o b.

Así que ahora, su gráfico de referencia de objeto tendrá una pequeña parte desconectada del gráfico que contiene ayb. Ambos todavía tienen referencias el uno al otro, pero nada más tiene una referencia a ellos. Como no se puede acceder desde el conjunto de raíz, el GC sabe que no se están utilizando y puede recolectar basura, aunque tengan referencias entre sí.

(tenga en cuenta que esta es una descripción un tanto simplificada de la recolección de basura, pero sigue siendo un modelo útil/razonable mental de cómo funciona)

Así que la respuesta corta es - "Sí, usted tiene una referencia circular . Pero esto no es un problema, porque ambos objetos se recogerán una vez que ambos ya no se puedan ver "

Cuestiones relacionadas