Ce face WeakReference
O variabilă obișnuită ține obiectul în memorie cât timp există. Un WeakReference „privește” obiectul fără să-l rețină: dacă nu mai există alte referințe la el, colectorul de gunoi (garbage collector) îl poate șterge. target returnează obiectul cât timp există și null după ce a fost șters.
Momentul ștergerii nu este previzibil: poate fi imediat sau mult mai târziu. De aceea verifici mereu target pentru null și nu te bazezi pe când devine null. Ca la Expando, numerele, textele, bool și record-urile nu sunt permise ca țintă.
Se folosește pentru cache-uri care nu trebuie să blocheze eliberarea memoriei, de exemplu imagini mari încărcate o dată și refolosite doar dacă mai sunt în memorie.
Parametri
| Parametru | Descriere |
|---|---|
target |
Obiectul urmărit. |
Ce returnează
target: obiectul sau null.
Exemple
Exemplul 1: target cât timp obiectul este folosit
Cât timp variabila imagine există, obiectul nu poate fi șters, deci target nu este null.
class Imagine {
final String nume;
final int kb;
Imagine(this.nume, this.kb);
}
void main() {
var imagine = Imagine('harta_iasi.png', 4096);
var ref = WeakReference(imagine);
print(ref.target?.nume);
print(identical(ref.target, imagine));
try {
WeakReference<Object>('text');
} on ArgumentError {
print('Textele nu pot fi ținte');
}
}
Rezultat
harta_iasi.png
true
Textele nu pot fi ținte
Exemplul 2: Un cache care nu reține memoria
Dacă imaginea a fost ștearsă între timp, cache-ul o încarcă din nou. Când se întâmplă asta depinde de colectorul de gunoi, așa că rezultatul de mai jos este un exemplu.
class Imagine {
final String nume;
Imagine(this.nume) {
print('încarc $nume de pe disc');
}
}
final cache = <String, WeakReference<Imagine>>{};
Imagine incarca(String nume) {
var existenta = cache[nume]?.target;
if (existenta != null) return existenta;
var noua = Imagine(nume);
cache[nume] = WeakReference(noua);
return noua;
}
void main() {
var a = incarca('logo.png');
var b = incarca('logo.png');
print(identical(a, b));
}
Rezultat posibil (diferă la fiecare rulare)
încarc logo.png de pe disc
true
Greșeli frecvente
- Folosești
ref.target!fără verificare. Obiectul poate dispărea oricând; verificănull.