次のコードがある場合:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
PClassはガベージコレクションされますか?それとも、イベントが発生するたびにイベントを起動し続けますか?ガベージコレクションを許可するには、次のことを行う必要がありますか?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
「pClassをガベージコレクションする」という特定の質問の場合:イベントサブスクリプションは(パブリッシャーとしての)pClassのコレクションには影響しません。
一般的なGC(特にターゲット)の場合:MyFunctionが静的かインスタンスベースかによって異なります。
インスタンスメソッドへのデリゲート(イベントサブスクリプションなど)には、インスタンスへの参照が含まれます。はい、イベントサブスクリプションはGCを防ぎます。ただし、イベントを発行するオブジェクト(上記のpClass)が収集の対象になるとすぐに、これは問題ではなくなります。
これは一方向であることに注意してください。つまり、次の場合:
publisher.SomeEvent += target.SomeHandler;
「パブリッシャー」は「ターゲット」を存続させますが、「ターゲット」は「パブリッシャー」を存続させません。
そのため、pClassがとにかく収集される場合、リスナーをサブスクライブ解除する必要はありません。ただし、pClassが長期間(MyFunctionのインスタンスよりも長い)存続している場合、pClassはそのインスタンスを存続させることができるため、ターゲットを収集する場合は、サブスクライブを解除する必要がありますwould.
ただし、静的イベントは、このため、インスタンスベースのハンドラーと併用すると非常に危険です。
はい、pClassはガベージコレクションされます。イベントサブスクリプションは、pClassへの参照が存在することを意味しません。
そのため、pClassをガベージコレクションするためにハンドラを切り離す必要はありません。
メモリの一部が参照されなくなった瞬間に、ガベージコレクションの候補になります。クラスのインスタンスが範囲外になると、プログラムから参照されなくなります。使用されなくなったため、安全に収集できます。
何かが収集されるかどうかわからない場合は、次の質問を自問してください:まだ参照が存在しますか?イベントハンドラーは、オブジェクトインスタンスによって参照されますが、その逆ではありません。
pClass
はガベージコレクションされます。ただし、上記のコードスニペットが別のクラス内にある場合、pClass
をnull
に設定しないと、そのクラスのインスタンスがクリアされない場合があります。