5

独自のメソッドでクラス インスタンスを破棄したい。例えば:

obj = Object()
obj:destroy()
type(obj) == nil

オブジェクトは C で実装されています。それは可能ですか?

それが不可能な場合、2 番目の方法は次のとおりです。

_G["obj"] = nil
collectgarbage()

ありがとう!

4

3 に答える 3

5

独自のメソッドでクラス インスタンスを破棄したい。

これは絶対に避けるべきです。絶対に必要な場合にのみ、Lua で明示的なデストラクタ ルーチンを公開してください。

これを処理する正しい方法は、メタメソッドを使用して__gcLua C オブジェクトにメタテーブルを与えることです。このメタメソッドは、Lua ガベージ コレクションがオブジェクトを収集する直前に呼び出されます。

明示的なデストラクタ関数を絶対に使用する必要がある場合 (ガベージ コレクションを待たずに、高価なリソースが終了したらすぐにユーザーが解放できるようにするため)、次の 2 つのことを行う必要があります。

  1. ユーザーがオブジェクトを明示的に破棄する必要はありません。つまり、デストラクタまたはガベージ コレクションを介してオブジェクトを破棄できる必要があります。

  2. オブジェクトが明示的に破棄されている場合は、オブジェクトを破棄ないでください。ユーザーが明示的な破棄関数を呼び出した場合でも、このオブジェクトを取るすべての関数 (メンバー関数またはフリー関数) は機能する必要があります。これらの関数は何もしないかもしれませんが、それは問題ありません。しかし、プログラムがクラッシュすることはありません。

    基本的に、明示的に破棄されたとき、オブジェクトはまだ「生きている」状態である必要があります。オブジェクトをゾンビにする必要があります。生きていますが、あまり役に立ちません。そうすれば、プログラムが正しく動作しなくても、プログラムは引き続き機能します。

于 2012-07-06T16:04:15.487 に答える
3

あなたの例では単純obj = nilで十分です。object のコンテンツを破棄しないことに注意してください。変数にあった参照を削除するとobj、メモリ内のどこかにある実際のオブジェクトの参照が 1 つ少なくなり、参照が 0 に達した場合は、GC の対象となる参照が解除されます。

オブジェクトが破壊時に実行する外部タスクを持っていない場合は、それで十分です。すべての参照をスコープ外にするか、それらの参照を含む変数/テーブルメンバーを別のものまたはnil. それ以外の場合は、最初にオブジェクト固有のデストラクタを呼び出してから、参照を削除する必要があります。

そのようなデストラクタがどこからでもすべての参照を自動的に削除することはできませんが、少なくともオブジェクトの内部状態をクリアし、オブジェクトが使用できなくなった、または再初期化する準備ができているという内部フラグを設定できます。

于 2012-07-06T12:35:45.553 に答える