好的 Free 帶你上天堂 (咦?) 圖片來源 |
最近看到一篇關於葡萄牙人寫的文章:FreeAndNil... Esqueça
內文是說明在物件導向的時代,JAVA、C# 這類的語言都有垃圾自動回收機制,進化中的 Delphi 其實也有。
接著便開始說明了使用 FreeAndNil 讓我們的原始碼非常噁心的經過。
提出的解法是使用 Interface!
原先我們的寫法可能是:
還是先來說說 Interface 的結構好了
以 Help 的 Interface 範例來看:
IMyInterface = interface procedure P1; procedure P2; end; TMyImplClass = class procedure P1; procedure P2; end; TMyClass = class(TInterfacedObject, IMyInterface) FMyImplClass: TMyImplClass; property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface; end;
實戰時我們程式大概會這樣寫:
var MyClass: TMyClass; MyInterface: IMyInterface; begin MyClass := TMyClass.Create; MyClass.FMyImplClass := TMyImplClass.Create; MyInterface := MyClass; MyInterface.P1; // calls TMyClass.MyP1; MyInterface.P2; // calls TImplClass.P2;
然後就
得到 Memory Leak!!!
眼睛業障有點重 (笑)
其實,我們只要這樣寫就可以了:
var MyInterface: IMyInterface; begin MyInterface := TMyClass.Create; MyInterface.P1; MyInterface.P2;
然而,葡萄牙的這位作者提供了一種介面靜態實作的觀點,簡化寫法如下:
TMyTestClass = class(TInterfacedObject, IMyInterface) constructor Create(); class function New: IMyInterface; procedure P1; procedure P2; end; //呼叫時寫法如下: TMyTestClass.New.P1; TMyTestClass.New.P2;
一切真是太美好啦~~~~
BUT!人生最厲害的就是這個 BUT!
不知道你有沒有使用過 IOUtils 單元;
TPath、TDirectory、TFile三個物件都是採用 Record 宣告,實際寫法類似:
TPath.GetHomePath
這種使用方式也很方便,一樣不需要做釋放處理。
我們來寫寫看上述的範例使用 Record 的寫法:
TMyTestRecord = record class procedure P1;static; class procedure P2;static; end; //呼叫時寫法如下: TMyTestRecord.P1; TMyTestRecord.P2;
這種範例場合,似乎是 Record 比較簡單使用呢!
1. 以上就是整理拋棄 FreeAndNil 的方式,您是否有其它的看法呢?歡迎在文末留言!
2. 關於 Interface 的應用上,這位葡萄牙作者的部落格內容非常充實,有興趣深造的可以參考文末的連結。
See also:
沒有留言:
張貼留言