Od dawna się nad tym zastanawiam i nadal nie rozumiem. Istotą metody Free
jest to, że najpierw sprawdza czy referencja jest nil
em i jeśli nie to wywoływany jest destruktor Destroy
. Dzięki temu można bezpiecznie zwolnić dany obiekt kilka razy. Tyle tylko, że normalnie używa się Free
, a nie FreeAndNil
, więc takie zabezpieczenie o dupę rozbić, bo w typowym kodzie po prostu nie zadziała — drugie wywołanie Free
spowoduje rzucenie wyjątku AV
/SIGSEGV
.
Według mnie — kolejne zwolnienie tego samego obiektu powinno spowodować wyrzucenie wyjątku o naruszeniu pamięci, bo to nie jest normalne, że się kilka razy zwalnia ten sam blok pamięci. Jeśli tak jest, to — znów, według mnie — programista popełnił błąd i napisał nieprawidłowy kod, który powinien naprawić usuwając nadmiarowe instrukcje zwalniające.
A tu w dokumentacji taki kwiatek:
It is bad programming practice to call Destroy directly. It is better to call the Free method, because that one will check first if Self is different from Nil.
Nie dość, że sugerują Free
, to wołanie Destroy
nazywają złą praktyką. :|
Czyli podsumowując, kod projektu powinien działać tak samo prawidłowo nawet jeśli wymieni się w nim wszystkie Free
na Destroy
. Kiedyś sprawdziłem to w projekcie Richtris i niestety nie zadziałało — poleciał wyjątek. Problem w tym, że w nim używam komponentów wizualnych i bug jeden wie co z nimi robi klasa formularza. Natomiast teraz zrobiłem to samo w Fairtrisie i wszystko działa prawidłowo — nie ma żadnych wyjątków, a więc każdy utworzony obiekt jest zwalniany tylko raz (i tak być powinno).
Może mi ktoś powiedzieć dlaczego Free
jest promowany i dlaczego wielokrotne zwalnianie danego obiektu nie jest powszechnie uznawane za błąd w projekcie? O czymś nie wiem, czy po prostu jest to przyzwolenie na delikatne niechlujstwo, aby nieco łatwiej było pisać kod zarządzający obiektami?