如果我有以下代码:
MyClass pClass = new MyClass(); pClass.MyEvent += MyFunction; pClass = null;
pClass会被垃圾收集吗?或者它会在它们发生的时候仍然停止发射?我是否需要执行以下操作才能进行垃圾回收?
MyClass pClass = new MyClass(); pClass.MyEvent += MyFunction; pClass.MyEvent -= MyFunction; pClass = null;
Marc Gravell.. 199
对于特定问题"将pClass收集垃圾":事件订阅对pClass(作为发布者)的集合没有影响.
对于一般的GC(特别是目标):它取决于MyFunction是静态的还是基于实例的.
实例方法的委托(例如事件订阅)包括对实例的引用.所以,是的,事件订阅将阻止GC.但是,只要发布事件的对象(上面的pClass)有资格进行收集,这就不再是一个问题.
请注意,这是单向的; 即如果我们有:
publisher.SomeEvent += target.SomeHandler;
然后"发布者"将保持"目标"活着,但"目标"不会让"发布者"保持活力.
所以没有:如果要收集pClass,则无需取消订阅听众.但是,如果pClass是长寿命(比MyFunction的实例更长),然后pClass可以保持该实例活着,所以它会如果要收集目标有必要取消.
但是,出于这个原因,静态事件与基于实例的处理程序一起使用时非常危险.
对于特定问题"将pClass收集垃圾":事件订阅对pClass(作为发布者)的集合没有影响.
对于一般的GC(特别是目标):它取决于MyFunction是静态的还是基于实例的.
实例方法的委托(例如事件订阅)包括对实例的引用.所以,是的,事件订阅将阻止GC.但是,只要发布事件的对象(上面的pClass)有资格进行收集,这就不再是一个问题.
请注意,这是单向的; 即如果我们有:
publisher.SomeEvent += target.SomeHandler;
然后"发布者"将保持"目标"活着,但"目标"不会让"发布者"保持活力.
所以没有:如果要收集pClass,则无需取消订阅听众.但是,如果pClass是长寿命(比MyFunction的实例更长),然后pClass可以保持该实例活着,所以它会如果要收集目标有必要取消.
但是,出于这个原因,静态事件与基于实例的处理程序一起使用时非常危险.
是的,pClass将被垃圾收集.事件订阅并不意味着pClass存在任何引用.
所以不,你不必分离处理程序,以便pClass被垃圾收集.
一段内存不再被引用的那一刻它就成了垃圾收集的候选者.当您的类的实例超出范围时,您的程序将不再引用它.它不再使用,因此可以安全地收集.
如果你不确定某些东西会被收集,请问自己以下问题:是否仍然存在对它的引用?事件处理程序由对象实例引用,而不是相反.