2012-01-28 12 views
6

Ho una classe A con una variabile di istanza ImageView. Attualmente utilizzo setTag() per tornare da ImageView all'istanza della Classe A. Potrebbe essere presente un loop circolare? Ho anche sentito parlare di riferimenti deboli. Qual è il modo migliore per arrivare alla classe madre A di ImageView?tiene traccia della classe genitore dal membro imageview

Il mio scenario di utilizzo è che sto trascinando l'ImageView sullo schermo e ho bisogno di accedere alla classe A per informazioni sul ImageView che viene trascinato.

+0

Perché non utilizzare il proprio HashSet per tracciare i propri riferimenti (ID di ImageView -> Istanza ClassA) ? – Olegas

risposta

3

Credo che Dalvik VM non abbia problemi con il rilevamento di riferimenti circolari.

Ecco Q/A che lo discute: Circular References in Java

Solo un'implementazione molto ingenuo avrebbe un problema con circolari riferimenti.

Vorrei usare setTag per contenere riferimento all'oggetto correlato. Inoltre, l'uso di setTag/getTag su View è un approccio standard e consigliato per ottenere varie ottimizzazioni su Android, anche se si trova in campioni Android. Alcuni riferimenti:

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

Android Custom Listview

Se GC di Android avrebbe problemi a rilevare tali dipendenze, Android non avrebbe funzionato come funziona. Vai avanti e usa View.setTag se è adatto al tuo scopo.

+0

stavo cercando conferma sul web che settag è un riferimento debole. non riesco a trovarlo però? – prostock

+0

Codice sorgente studio di Vista: protetto Oggetto mTag; setTag vuoto pubblico (tag Object finale) { mTag = tag; } –

+0

setTag non ha nulla a che fare con WeakReferences. Tuttavia, potresti inserire un WeakReference nel tag se questo è ciò che stai cercando di ottenere. Detto questo, assicurati di capire che cosa WeakReference ti metta per primo. –

0

Il modo migliore per sbarazzarsi di riferimenti circolari è quello di rendere la variabile di istanza in A una variabile finale:

private final ImageView myImageView; 

Questo vi costringerà a inizializzare la variabile nel costruttore di A. Se si passa in modo esplicito il riferimento a ImageView nelle nuove chiamate, eviterete le possibilità di riferimenti circolari.

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

I riferimenti circolari in java non rappresentano un problema per il GC. Questo non è un problema a causa di un concetto chiamato "raggiungibilità".

Si può pensare ai riferimenti oggetto come a un grafo orientato, in cui i nodi sono oggetti ei bordi sono riferimenti a oggetti. Ci sono un insieme di nodi nel grafico chiamato "root root" - questi sono (approssimativamente) gli oggetti che sono direttamente accessibili ad alcuni thread nel vm. Cose come variabili locali in qualsiasi chiamata di funzione nello stack, campi statici nelle classi, ecc.

Quando si esegue una garbage collection, la VM inizia con questi nodi radice e li contrassegna come "in uso". Quindi, per ogni spigolo che porta fuori da questi nodi in uso, (cioè, per ogni oggetto a cui si fa riferimento dagli oggetti in uso), segna anche come in uso, e così via, finché non rimane nulla marchio. E poi, qualsiasi oggetto che non è stato contrassegnato come "in uso", sa che può tranquillamente raccogliere i rifiuti.

Ora, diciamo per esempio siete in qualche modo, e si ha il seguente codice:

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

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

ora avete un riferimento circolare tra A e B. Entrambi questi oggetti fanno parte del set di root, poiché sono una variabile locale in una chiamata di metodo che è in pila.

Quindi, quando si esce da quel metodo, sia a che b non faranno più parte del set radice. E finché non hai fatto riferimento a loro da qualche altra parte, non c'è nient'altro che contenga un riferimento a a o b.

Quindi ora il grafico di riferimento dell'oggetto avrà una parte del grafico che presenta a e b un po 'scollegata. Entrambi hanno ancora riferimenti l'uno all'altro, ma nient'altro ha un riferimento a loro. Dal momento che non sono raggiungibili dal set di root, il GC sa che non vengono utilizzati e li può raccogliere, anche se hanno riferimenti l'uno all'altro.

(si noti che questa è una descrizione un po 'semplificata di raccolta dei rifiuti, ma è ancora un/ragionevole modello mentale utile di come funziona)

Quindi la risposta breve è - "Sì, si ha un riferimento circolare Ma questo non è un problema, perché entrambi gli oggetti verranno raccolti quando entrambi non saranno più raggiungibili "

Problemi correlati