Bug 181642 [Viewers] [JFace] Why doesn't BaseLabelProvider.dispose() call clearListeners()?
Build ID: N20070405-0010 This is easy for me to work around, so it's not that big a deal, but I'm surprised that Eclipse 3.3's BaseLabelProvider.dispose() does not call clearListeners(). Does that seem like a bug to you, or not? BaseLabelProvider is a convenience default implementation of IBaseLabelProvider, and thus it has addListener() and removeListener(), so that anyone who wants to listen to the label provider for changes can do so. But when I implement a class that supports listeners, and also has a dispose() method -- as IBaseLabelProvider does -- I usually have the dispose() method clear out the list of listeners. This can be helpful in preventing JVM memory leaks. Since BaseLabelProvider is a convenience implementation of IBaseLabelProvider, and since it takes care of addListener() and removeListener() for me, I would think it would also clear out the list of listeners when its dispose() is called. You could argue that BaseLabelProvider.dispose() should not clear the list of listeners, because dispose() really exists for the sake of freeing SWT resources, which has nothing to do with listeners. I guess that's a reasonable argument. But as far as I know, once any object's dispose() has been called, the object should be considered essentially dead; so again, for the sake of avoiding possible memory leaks, it would make sense to me that dispose() would call clearListeners(). It's pretty common to remove listeners in dispose() -- for example, CVSLightweightDecorator does that.
bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/BaseLabelProvider.java
/* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
     */
    public void removeListener(ILabelProviderListener listener) {
        removeListenerObject(listener);
    }
    
    /**
	 * Fires a label provider changed event to all registered listeners Only
	 * listeners registered at the time this method is called are notified.
	 * 
	 * @param event
	 *            a label provider changed event
	 * 
	 * @see ILabelProviderListener#labelProviderChanged
	 */
	protected void fireLabelProviderChanged(final LabelProviderChangedEvent event) {
		Object[] listeners = getListeners();
		for (int i = 0; i < listeners.length; ++i) {
			final ILabelProviderListener l = (ILabelProviderListener) listeners[i];
			SafeRunnable.run(new SafeRunnable() {
				public void run() {
					l.labelProviderChanged(event);
				}
			});
		}
	}
}