Od jakiegoś czasu w zbiorze propozycji nowych “ficzerów” do PHP znajduje się RFC pod tajemniczą nazwą “Weak references”. W czym właściwie jest rzecz i czym są owe “słabe referencje” ? Cały pomysł został zaczerpnięty przez autorów z Javy, C# i Pythona. Rozwiązuje on problem związany ze zwalnianiem pamięci i garbage collectorem. Problem, kiedy mamy zbyt dużo referencji do jakiś obiektów i nie zostają one nigdy zebrane przez GC. Słaba referencja, w przeciwieństwie do standardowej “mocnej” nie powoduje zwiększenia licznika ilości referencji, po którym GC rozpoznaje, czy może już dany obiekt usunąć z pamięci.
Kiedy się to może przydać ? Prosty przykład, stosujemy wzorzec obserwator. Obserwowany obiekt zwany też podmiotem rejestruje subskrybentów, których będzie powiadamiał o zmianie swojego stanu. Takich subskrybentów może być bardzo wielu. Może się zdarzyć, że któryś subskrybent mógłby już zostać usunięty z pamięci przez GC, gdyby nie ta ostatnia referencja, którą trzyma podmiot. W efekcie przy wielu obiektach subskrybentów, tracimy niepotrzebnie pamięć. Rozwiązaniem jest zastosowanie słabej referencji. Dzięki niej, w momencie, gdy wszystkie inne zewnętrzne referencje do danego subskrybenta wygasną zostanie on od razu zebrany przez GC.
Implementacja zaproponowana w RFC postuluje stworzenie klasy SplWeakRef. Jej zastosowanie będzie wymagało tylko przekazania do jej konstruktora zmiennej do obiektu, który ma być słabą referencją.
class Foo {}
$foo = new Foo; //reference count 1
$bar = $foo; //reference count 2
$slabaReferencja = new SplWeakRef($foo); //reference count 2
Jestem ciekaw co sądzicie o tej propozycji ? Osobiście wydaje mi się dość ciekawa, natomiast chyba pole zastosowań jest naprawdę bardzo małe, a potencjalnie może być ten “ficzer” bardzo niebezpieczny w rękach początkujących programistów. Osobiście zamiast tego mechanizmu, wolałbym możliwość deklarowania klas tak, by ich obiekty były przekazywane przez kopię, tak jak typy proste. Moim zdaniem dużo bezpieczniejsze rozwiązanie a efekt podobny.