193

次のコードがある場合:

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;

pClass はガベージ コレクションされますか? それとも、イベントが発生するたびにイベントを発生させ続けますか? ガベージ コレクションを許可するには、次のことを行う必要がありますか?

MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
4

4 に答える 4

226

「pClass はガベージ コレクションされますか」という特定の質問について: イベント サブスクリプションは、pClass のコレクションに (パブリッシャーとして) 影響を与えません。

一般的な GC (特にターゲット) の場合: MyFunction が静的かインスタンスベースかによって異なります。

インスタンス メソッドへのデリゲート (イベント サブスクリプションなど) には、インスタンスへの参照が含まれます。そうです、イベント サブスクリプションは GC を防ぎます。ただし、イベントを発行するオブジェクト (上記の pClass) がコレクションの対象になるとすぐに、これは問題ではなくなります。

これは一方向であることに注意してください。つまり、次の場合:

publisher.SomeEvent += target.SomeHandler;

その場合、「パブリッシャー」は「ターゲット」を存続させますが、「ターゲット」は「パブリッシャー」を存続させません。

したがって、いいえ: pClass がとにかく収集される場合は、リスナーのサブスクライブを解除する必要はありません。ただし、pClass の寿命が長い (MyFunction を持つインスタンスよりも長い) 場合、pClass はそのインスタンスを存続させることできるため、ターゲットを収集するには、サブスクライブを解除する必要があります。

ただし、静的イベントは、この理由から、インスタンス ベースのハンドラーで使用すると非常に危険です。

于 2008-11-18T09:43:27.147 に答える
9

はい、pClassガベージコレクションされます。イベント サブスクリプションは、 への参照が存在することを意味するものではありませんpClass

いいえ、pClassガベージ コレクションを行うためにハンドラーをデタッチする必要はありません。

于 2008-11-18T09:49:23.563 に答える
8

メモリの一部が参照されなくなった時点で、ガベージ コレクションの対象になります。クラスのインスタンスがスコープ外になると、プログラムによって参照されなくなります。使用しなくなったので、安全に回収できます。

何かが収集されるかどうかわからない場合は、次の質問を自問してください。それへの参照はまだ存在しますか? イベント ハンドラーはオブジェクト インスタンスによって参照されますが、その逆ではありません。

于 2008-11-18T10:55:37.097 に答える
0

pClassガベージコレクションされます。pClassただし、上記のコード スニペットが別のクラス内にある場合、 に設定しないと、そのクラスのインスタンスがクリアされない可能性がありますnull

于 2012-06-07T13:31:51.600 に答える