Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: destroy/cleanup mediator before removal  (Read 18033 times)
nilsm
Jr. Member
**
Posts: 19


View Profile Email
« on: January 16, 2008, 12:39:08 »

Hi there,

I read in the best practice guide that you should call a 'destroy' method before removing a Mediator from the Facade. This of course makes perfect sense, since a removed Mediator probably has quite a few view component dependencies that need cleaning up.

My main question is - why isn't that 'destroy' method part of the architecture?

Second question: Is there a chance in future updates that 'removeMediator' could return the instance that was removed? At the moment, to call 'destroy()', I need to retrieve the instance, then call destroy(), then remove the instance, whereas it could all go into one line:

facade.removeMediator(name).destroy();

Or am I missing something important?

cheers - Nils.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: January 16, 2008, 08:51:08 »

Which page in the Best Practices document did you read that you were supposed to call a destroy method on the Mediator?. I searched the document for the word destroy and didn't find it.

And it might be possible to make removeMediator return the removed Mediator in 2.0. The last several changes to the framework have been about helping mediators to go away altogether by  making sure there were no references left anywhere. However, if you ignore the return, then the returned instance falls out of scope and is eaten by the gc. So this seems possible. It's not always the case that you'd want to loose the instance you might register it again later.

Under consideration.

-=Cliff>
Logged
nilsm
Jr. Member
**
Posts: 19


View Profile Email
« Reply #2 on: January 18, 2008, 08:16:39 »

Hi Cliff,

thanks for the quick reply. I don't remember where I read it - maybe I remembered incorrectly or it's just something I wanted to do on my current project. I'll let you know if I come across it again somewhere.

In any case though, what are your thoughts on garbage collection for mediators that aren't used anymore? They usually listen to events from view components, so references are likely in more places than just the PureMVC framework. We could use weak references when adding event listeners in Flash/Flex - but I reckon it would be nice to have a function that can be overridden when the Mediator is removed.

I'm just getting in to all this - sorry if it's already been discussed elsewhere.

- Nils.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: January 18, 2008, 02:56:05 »

I'd just like to report that your suggestion has been implemented in 2.0.

Now the Model, View and Facade's removeMediator and removeProxy methods both return a reference to the Mediator or Proxy they just removed from the View or Model.

This is perfectly backward compatible, if you were ignoring or expecting no return before, you can keep on ignoring it, and there's no problem.

However, this change makes it possible that when you remove a mediator or proxy that you may only be putting it on the bench for the moment and may want to put it back in the game (reregister it) later. Of course commands are stateless and not created until invoked, and so therefore removeCommand still returns void.

And you are correct, in that your Mediators, though removed from the view, will still have references to them elsewhere since they do add event listeners to the view components. But that's it, there should be no other references to a given mediator anywhere in the system.

That destroy method advice was probably something you found in a post somewhere, I would've recommended it, but I didn't think I touched on it in Best Practices.

Here's the idea:

 1) If you plan to remove a mediator from the view and have it go away altogether at GC time, then you should implement a destroy method on the Mediator which removes all event listeners that it has set.

 2) The framework is now returning the removed mediator or proxy so that you may store it for later reregistration, so

 3) This method will not be called by the framework because it is not the framework's job to make the Mediator die and go away, only to remove it from the view so that it is no longer reachable by the rest of the system, either by retrieveMediator or by sendNotification.

 4) To make sure your mediator is dead dead dead (in AS3/2.0):

:
   var mediator:MyMediator;
   mediator = facade.removeMediator(MyMediator.NAME);
   mediator.destroy();

-=Cliff>
Logged
sectore
Courseware Beta
Full Member
***
Posts: 29



View Profile WWW Email
« Reply #4 on: January 19, 2008, 01:01:36 »

Looking for the advice of the destroy() method using facade.removeMediator(MyMediator.NAME);?
Maybe you've founded it in the article called "10 tips for working with PureMVC" at #8:
8. Remove unused Mediators
In some cases you don’t use a Mediator and its View Components anymore. Then remove the Mediator using facade.removeMediator(MyMediator.NAME); in conjunction with a self created destroy() method to remove the ViewComponent including all listeners, timer, references, etc. for a successful garbage collection.

Anyway, an implementation like this in 2.0 would be nice. Is there a way to call such a destroy() method removing Mediator within View.as (e.g. mediatorMap[ mediatorName ].destroy() in removeMediator() ) ? So we could use facade.removeMediator(MyMediator.NAME); as before and the View.as does the job for executing Mediators destroy().

-sectore
« Last Edit: January 19, 2008, 01:24:39 by sectore » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #5 on: January 19, 2008, 03:17:50 »

I've actually just modified the removeMediator and removeProxy methods to return a reference to the Mediator or Proxy that was returned. It will be your business at implementation time whether you want to hang onto that and re-register it later or call a custom destroy method and then let it fall out of scope. Therefore, the framework will not call this method, and it will not be added to the interfaces or base classes,  because I don't want to impose the idiom from a framework standpoint.

-=Cliff>
Logged
nilsm
Jr. Member
**
Posts: 19


View Profile Email
« Reply #6 on: January 25, 2008, 05:04:03 »

Thanks all for the detailed response!

I'm very happy to hear that this has been added Cliff - cheers. I'm thinking that a generic Mediator subclass that includes an stub destroy() method might be a good addition to the PureMVC utilities library that you mentioned elsewhere.

- Nils.

Logged
nilsm
Jr. Member
**
Posts: 19


View Profile Email
« Reply #7 on: January 28, 2008, 08:59:45 »


I just wanted to revisit this subject now that I've had more experience with PureMVC. In my current code a 'destroy()' method for Mediators is essential and, since Cliff doesn't see it the same way, I was wondering whether there is a better way to implement my Mediators.

When user navigates to a section, I do this:

- create the section's container view component
- create the section's Mediator and add it to the facade
- the Mediator then creates other Mediators to handle specific components that are exposed by the section's container component (eg. a MenuBar or a List)

When the user navigates away from the section, I remove the Mediator and call its 'destroy()' method, which in turn removes child elements, event listeners and the other Mediators it has created.

That seems like a straightforward strategy to me but it makes 'destroy()' essential, so I was wondering how others implement Mediators without the 'destroy()' method.

Thanks for any input,

Nils.

Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #8 on: January 29, 2008, 12:40:31 »

Hi Nils,

There is nothing to say that you cannot implement a destroy method in your Mediator. You can simply subclass Mediator and add the method.

If you are concerned about being able to invoke it against an interface, you may also extend the IMediator interface and add the signature. Of course, make all your new Mediators that need this method be implementors of your new interface.

I'll give serious consideration to whether this is 'essential' enough to include in the framework, but must say I've seen plenty of PureMVC applications without need for it.

It's not that I don't see the reason for the method. I agree that if you're adding and removing Mediators often, you'll probably need a destroy method.

But it's not like you can't add it easily when you need it. The framework isn't going to call it, so it's difficult to want to impose this from the framework standpoint.

My concern with every suggestion for framework change is striking the balance between the opposing perceptions of full-featuredness for advanced users and overwhelming and daunting to new users.

-=Cliff>
Logged
nilsm
Jr. Member
**
Posts: 19


View Profile Email
« Reply #9 on: January 30, 2008, 02:59:32 »

Morning Cliff,

thanks for the detailed reply - as always :)

My concern with every suggestion for framework change is striking the balance between the opposing perceptions of full-featuredness for advanced users and overwhelming and daunting to new users.

I completely agree with and strongly support that point of view. I wasn't really suggesting you add the method - I mainly wanted to check whether there was a better way of implementing my code.

I'm happy to extend IMediator - in due course, maybe this would make a good addition to the library you mentioned elsewhere.

cheers - Nils.

Logged
JCabot
Courseware Beta
Jr. Member
***
Posts: 11


View Profile Email
« Reply #10 on: February 15, 2008, 11:36:59 »

I just thought I would let you know a way that I have implemented a dispose/destroy method just to get your thoughts on it. It means you don't have to keep casting things to their concrete mediator in order to call destroy on them, instead just use the IDisposable interface.

Have a public interface for disposable objects
:
public interface IDisposable
{
function dispose():void;
}

Implement this in your mediators/whereevers
:
public class MyMediator extends Mediator implements IMediator, IDisposable
{
...
public function dispose():void
{
viewComponent.removeEventListener(Event, function);
...
}
...
}


Register a command responsible for disposing objects
:
public class RemoveAndDisposeCommand extends SimpleCommand implements ICommand
{
override public function execute(notification:INotification):void
{
var mediatorName:String = notification.getBody() as String;
var toDestroy:IDisposable = facade.removeMediator(mediatorName) as IDisposable;

if (toDestroy != null) toDestroy.dispose();
}
}

Then if you want to remove a mediator from the system, you can simply write:
:
sendNotification(ApplicationFacade.REMOVE_AND_DISPOSE, mediatorName);
or whatever name you registered the command with

of course, this only works when removeMediator returns a reference to the mediator that was removed...
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #11 on: February 15, 2008, 04:25:13 »

Jason,

Thats a pretty nice solution to the problem. In fact its so clean, I'd like to add it to the repository as a utility.

And yes, the granularity of a utility does go this far down. An Interface and a Command. But together they solve the problem perfectly without requiring the framework to be modified, and you can use it or not, depending on your needs.

This is the way the framework will be extended. One utility at a time.

Would you care to be the utility owner? If so, send me a private message or an email and I'll show you round the Manifold Project a bit. You can this Contributor Central post: for info on project ownership in the new repository: http://forums.puremvc.org/index.php?topic=142.0

It's also good to use each utility in a demo somewhere. Once you've done one, it's easy to do another, and another and another... :)

-=Cliff>
Logged
mnkyhead
Courseware Beta
Newbie
***
Posts: 4


View Profile Email
« Reply #12 on: March 03, 2008, 09:33:32 »

So did I miss the release of 2.0, or is it still beta?  Can I get it for AS3?
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #13 on: March 03, 2008, 09:42:26 »

Yes, you already missed the release. We're fresh out.

No, actually, I'm slamming like a madman getting it ready for release. I finished a rewrite of the Best Practices doc this weekend, bringing it up to 2.0 and adding another 10 pages or so. Still have the Framework Overview with UML to update. That and bringing a few projects (there are 20 AS3 projects altogether now) up to 2.0 level and getting all the permissions on the public wiki straight.

I expect it'll be this week sometime that the actual release will be made. It will be worth the wait, though. There are a few surprises nobody was expecting.

-=Cliff>

Logged
Pages: [1]
Print