问题描述
将听众保持弱点的利弊是什么?
当然,大"专业"当然是:
将听众添加为弱referference意味着听众不需要打扰"删除"本身.
对于那些担心听众唯一对对象的引用的人,为什么不能有2种方法AddListener()和AddWeakReflistener()?
那些不关心拆除的人可以使用后者.
推荐答案
首先,在侦听器列表中使用弱率将使您的对象不同语义,然后使用硬引用.在硬引用案例中,AddListener(...)的意思是"有关特定事件的通知对象(S),直到我用removelistener(..)明确停止它,"通知提供的有关特定事件的对象(S),直到其他任何人都不会使用此对象(或明确停止使用removelistener).请注意,在许多情况下,有对象,聆听某些事件,并且没有其他参考文献将其与GC保持联系是完全合法的.记录器可以是一个示例.
您可以看到的,使用弱者不仅要解决一个问题("我应该牢记不要忘记在某个地方删除添加的听众"),而且还抬起另一个问题 - "我应该牢记我的听众可以停止在不再提及它的任何时候都会听."您无法解决问题,您只是将一个问题换成另一个问题.看,以任何方式您被迫清楚地定义,设计和跟踪您的听众的救生程序 - 一种或另一种方式.
因此,就我个人而言,我同意在听众列表中提到什么使用弱率更像是黑客而不是解决方案.值得了解的模式,有时可以帮助您 - 例如,使旧版代码效果很好.但这不是选择模式:)
P.S.另外,应该注意的是,什么弱ReReference引入了额外的间接水平,在某些情况下,事件发生率极高,可以降低性能.
其他推荐答案
这不是一个完整的答案,但是您所引用的力量也可能是其主要弱点.考虑如果动作听众被弱实施会发生什么:
button.addActionListener(new ActionListener() { // blah });
动作听众随时会收集垃圾!唯一对匿名类的引用是您添加它的事件并不少见.
其他推荐答案
我已经看到了大量的代码,其中听众未正确注册.这意味着他们仍然不必要地执行不必要的任务.
如果只有一个班级依靠听众,那么它很容易清洁,但是当25堂课依靠它时会发生什么呢?正确注册它们变得更加棘手.事实是,您的代码可以从一个引用侦听器的一个对象开始,最终以25个对象引用同一侦听器.
不使用WeakReference等同于承担消耗不必要的内存和CPU的大风险.它更复杂,更棘手,需要在复杂代码中使用硬参考的更多工作.
WeakReferences充满了专业人士,因为它们会自动清理.唯一的骗局是,您必须忘记在代码中其他地方保留硬参考.通常,这将在依靠此侦听器的对象中.
我讨厌代码创建匿名类的侦听器实例(如Kirk Woll所述),因为一旦注册,您就无法再注册这些侦听器了.您没有提及他们.恕我直言真的很糟糕.
当您不再需要时,您也可以null对听众的引用.您不再需要担心.
问题描述
What are the pros and cons of keeping listeners as WeakReferences?
The big 'Pro' of course is that:
Adding a listener as a WeakReference means the listener doesn't need to bother 'removing' itself.
For those worried about the listener having the only reference to the object, why can't there be 2 methods, addListener() and addWeakRefListener()?
Those who don't care about removal can use the latter.
推荐答案
First of all, using WeakReference in listeners lists will give your object different semantic, then using hard references. In hard-reference case addListener(...) means "notify supplied object about specific event(s) until I stop it explicitly with removeListener(..)", in weak-reference case it means "notify supplied object about specific event(s) until this object will not be used by anybody else (or explicitly stop with removeListener)". Notice, it is perfectly legal in many situations to have object, listening for some events, and having no other references keeping it from GC. Logger can be an example.
As you can see, using WeakReference not just solve one problem ("I should keep in mind to not forget to remove added listener somewhere"), but also rise another -- "I should keep in mind that my listener can stop listen at any moment when there is no reference to it anymore". You not solve problem, you just trade one problem for another. Look, in any way you've forced to clearly define, design and trace livespan of you listener -- one way or another.
So, personally, I agree with mention what use WeakReference in listeners lists is more like a hack than a solution. It's pattern worth to know about, sometimes it can help you -- to make legacy code work well, for example. But it is not pattern of choice :)
P.S. Also it should be noted what WeakReference introduce additional level of indirection, which, in some cases with extremely high event rates, can reduce performance.
其他推荐答案
This is not a complete answer, but the very strength you cite can also be its principal weakness. Consider what would happen if action listeners were implemented weakly:
button.addActionListener(new ActionListener() { // blah });
That action listener is going to get garbage collected at any moment! It's not uncommon that the only reference to an anonymous class is the event to which you are adding it.
其他推荐答案
I have seen tons of code where listeners were not unregistered properly. This means they were still called unnecessarily to perform unnecessary tasks.
If only one class is relying on a listener, then it is easy to clean, but what happens when 25 classes rely on it? It becomes much trickier to unregister them properly. The fact is, your code can start with one object referencing your listener and end up in a future version with 25 objects referencing that same listener.
Not using WeakReference is equivalent to taking a big risk of consuming unnecessary memory and CPU. It is more complicated, trickier and requires more work with hard references in the complex code.
WeakReferences are full of pros, because they are cleaned up automatically. The only con is that you must not forget to keep a hard reference elsewhere in your code. Typically, that would in objects relying on this listener.
I hate code creating anonymous class instances of listeners (as mentioned by Kirk Woll), because once registered, you can't unregister these listeners anymore. You don't have a reference to them. It is really bad coding IMHO.
You can also null a reference to a listener when you don't need it anymore. You don't need to worry about it anymore.