Don,
You're absolutely right, the associated Observer instances were not being removed from the View's observerMap when removeMediator was done.
I have corrected the problem, and updated the framework and unit tests. The new framework version is 1.5 and is now the currently downloadable version.
Since removing Mediators after their creation is seldom done and not really advised (see earlier in the thread for those just tuning in), this is not something that will change the behavior of any existing application or require any recoding.
The change entailed adding a compareNotifyContext method to Observer and IObserver. This allows the View to compare the Mediator being removed to a given Observer's Notification Context reference without breaking the Observer's encapsulation of that reference.
The removeMediator method of the View now goes through the observerMap (where notification name is key and an array of observers is value) and for each observer list, removes the Observers pointing to this specific Mediator reference. If this causes the Observer list length to fall to zero (no more observers for this notification name), the reference to the observer list is set to null, freeing it as well.
The Unit tests have been updated to test the new Observer.compareNotifyContext method.
Below are screenshots showing before and after a removeMediator test in the debugger. They show that the Observers are removed, and further, when the last observer in an observer list is removed, the list itself is removed.
Before
After
Note that the keys still exist in the array; both for removed Mediators and for Notifications that now have null observer lists.
Though the keys remaining are tiny and few, the act of adding a Mediator then removing it should be idempotent; it should, as a good nature hiker, leave no trace.
However, I've found no good way to remove the keys of an associative array other than to copy the array elements over to a new array, bringing over only the ones that are not null, then replacing the original array reference. The splice method only works for strict arrays, these are associative arrays.
Copying the arrays is the answer, but I'm not yet decided as to whether to have a cleanup function or to do it inline. This is an minor optimization that will be thought out and included in a future maintenance release.
Again, thanks for catching this and bringing it to my attention. The plan is to push the framework to an extremely stable state quickly and not touch it anymore. While this wasn't a fatal flaw, finding and dispatching any issues early on is the name of the game.
-=Cliff>