我知道這三種技術:
手動
uses System.Classes; procedure DoSomething; var sl: TStringList; begin sl := TStringList.Create; try finally sl.Free; // Invoking destructor end; end;參考計數/介面 (
標準庫中我腦海中最快的例子:TInterfacedObject)uses Xml.XMLDoc, Xml.XMLIntf; procedure DoSomething; var xmldoc: IXMLDocument; begin xmldoc := TXMLDocument.Create(nil) as IXMLDocument; end; // No reference to xmldoc anymore, freed automatically所有權
就像幾乎整個 VCLibrary 或這個:uses System.Generics.Collections; procedure DoSomething; var ol: TObjectList<TObject>; i: Integer; o: TObject; begin ol := TObjectList<TObject>.Create(true); // the list takes ownership of the objects try for i := 0 to 9 do begin o := TObject.Create; ol.Add(o); end; finally ol.Free; // does not only free the list but all objects in the list, too end; end;
還有更多嗎?
uj5u.com熱心網友回復:
Delphi中管理物件實體的記憶體管理模型有兩種:手動記憶體管理和自動參考計數。所有物件實體將手動或通過參考計數機制釋放。
但是當涉及到實際的編碼模式時,我們可以通過多種方式撰寫代碼以觸發物件實體的釋放,并且幾乎不可能將它們全部列出和分類。
說明所涉及的復雜性的最佳方法是提出其他問題:
您認為什么是記憶體管理技術?
例如,手動釋放物件實體需要呼叫解構式。但是有幾種常用的方法可以做到這一點:通過呼叫Free、Destroy或FreeAndNil。但是,Free最終FreeAndNil會呼叫Destroy. 那么問題來了,我們應該認為那些呼叫解構式的不同方法是相同的技術還是不同的技術?其他會觸發物件實體銷毀的自定義撰寫方法呢?
在釋放參考計數的物件實體時,您的示例顯示了間接的釋放方式 - 只是讓參考超出范圍。但是還有另一種釋放此類物件實體的方法,即顯式分配nil給此類參考。
procedure DoSomething;
var
xmldoc: IXMLDocument;
begin
xmldoc := TXMLDocument.Create(nil) as IXMLDocument;
...
xmldoc := nil;
...
end;
同樣,問題是我們是否認為這兩個不同的例子是相同的還是不同的?
在所有權方面,它只是一種將物件實體的發布委托給其他物體的方式。最后,在手動管理物件實體的情況下,某些代碼在某些時候會直接呼叫此類物件的解構式。雖然這顯然是一種不同于直接在物件參考上呼叫解構式而不經過額外的間接層的編碼模式,但最終實體將被手動釋放。
我們還可以轉移參考計數物件實體的所有權。如果您有一個包含介面參考的集合,那么這也可以視為所有權轉移,因為這些實體的釋放將取決于集合本身的釋放,即使涉及的代碼不會直接呼叫解構式,而是依賴于自動參考計數這樣做。
出現的下一個問題是:欄位呢?您的第一個示例顯示了本地物件實體的構造和銷毀。如果我們在類中有一個物件欄位并Free在其解構式中手動呼叫該欄位,我們應該將其視為手動技術還是所有權轉移,因為該內部物件實體的實際釋放將取決于其外部擁有物件的釋放.
參考計數還有其他方面。雖然編譯器會在適當的位置自動插入參考計數代碼(呼叫_AddRef和方法),但方法本身必須直接呼叫解構式才能真正釋放實體。在某種程度上,這只是所有權轉移的另一個例子,在編譯器的幫助下。_Release_Release
從一個角度來看,我們可以說你提到的這三種技術是釋放物件實體的(二)三種基本技術。但另一方面,它們的數量是無限的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/513251.html
標籤:德尔福内存管理引用计数
上一篇:在TRESTClient.BaseURL方法中強制使用最后一個“/”
下一篇:例程可以知道它運行的單元嗎?
