まず、ほとんどの場合、FreeAndNil は少し過剰です。オブジェクトのフィールドをデストラクタの外側またはグローバル (醜い) 変数で解放する場合に便利です。しかし、ほとんどの場合、無料で電話をかけるだけで十分です。
ご存知のように、オブジェクト変数は実際にはオブジェクトのデータへのポインターです。Free を呼び出すと、そのバッファーは解放されますが (もちろん、デストラクタが実行された後)、Object 変数は解放されたばかりのメモリ位置を指したままです。これは「ダングリング ポインター」と呼ばれます。ポインターがぶら下がっていることは、そのコンテキストでぶら下がっていることがわかっている限り、問題ではありません。例えば:
Procedure Myproc;
var vString : TStringList;
begin
//Here, vString is "dangling"
vString := TStringList.Create;
//Here, vString is valid
try
//Do some stuff
finally
vString.Free;
end;
//Here, vString is "dangling"... But who care, it's about to go out of scope and we won't use it again.
end;
FreeAndNil を呼び出すことは、いつ、どのように変数を解放できるか正確にわからないグローバル変数に対してより理にかなっています。そうは言っても、常に FreeAndNil を呼び出しても問題はありません (すべてのオンスのパフォーマンスを得ようとする非常にタイトなループを除きます)。
さて、COM オブジェクトについては... Mason が述べたように、それらは参照カウントされます。したがって、そのインターフェイスへの唯一の参照を保持している場合、呼び出すMyInterface := nil;
と解放されます。ただし、変数がスコープ外になると、コンパイラはクリーンアップ コードを追加してインターフェイス参照がデクリメントされるようにします。したがって、メモリ要件を最小限に抑えようとしている場合は、インターフェイスを nil に設定してください。そうでなければ、それほど問題ではありません。
配列に関しては...リスト内のすべてのアイテムでFreeを呼び出すことができます...オプションで、後でそれらをnilに設定します。