Views & Mediators life cycle

jimnastiq's Avatar

jimnastiq

25 Apr, 2012 03:03 PM

Hi there,

After searching on this knowledge base and through google, i can't get my view killed properly.
I'm runngin profiler on Flash builder to see if the previous view is killed but it persists on memory.

I've been using autoRemove for mediator's mapping, then i'm switching from a view to another simply by removing and adding views on the contextView :
`(contextView as IVisualElementContainer).removeElement(myViewA);

(contextView as IVisualElementContainer).addElement(new ViewB());`

i'm removing all listeners by overriding the onRemove method in my mediator.

Flash Builder Profiler tells me that a reference on my view is still in place (so GC won't do the job), and the reference that is pointing is actually the addElement on my contextView ... even if i ve done a removeElement on this particular view ...

Don't know if i'm clear, but don't hesitate to ask for more informations if needed.

Thx in advanced

  1. Support Staff 1 Posted by Ondina D.F. on 25 Apr, 2012 03:48 PM

    Ondina D.F.'s Avatar

    Hey Jim,

    First question:
    Have you tried to force the gc: “Run Garbage Collector” in the profiler?
    After removing it from the display list an object doesn’t get gc-ed right away, it just becomes a candidate for gc.

    Ondina

  2. 2 Posted by jimnastiq on 25 Apr, 2012 03:52 PM

    jimnastiq's Avatar

    Hi Ondina,

    First, thx for your reply and yep, i've tried manually with profiler and with System.gc() method. but no result.

  3. Support Staff 3 Posted by Ondina D.F. on 25 Apr, 2012 03:53 PM

    Ondina D.F.'s Avatar

    Next questions:
    What kind of a component is myViewA?
    Does it have sub-components?

  4. 4 Posted by jimnastiq on 25 Apr, 2012 03:56 PM

    jimnastiq's Avatar

    It's a component developped by myself (a view with list => itemrenderers and some buttons, ...) .

    I've already checked all of those sub views to see if listeners is still plugged ;)

  5. Support Staff 5 Posted by Ondina D.F. on 25 Apr, 2012 04:10 PM

    Ondina D.F.'s Avatar

    Have you tried to add/remove the components directly within the contextView (the display object) ?
    Can you try to add/remove a simple view without sub-components the same way you did with your myViewA and see if it gets gc-ed?

  6. Support Staff 6 Posted by Ondina D.F. on 25 Apr, 2012 04:12 PM

    Ondina D.F.'s Avatar

    Are you sure it is the same instance of myViewA that you are trying to remove?

  7. 7 Posted by jimnastiq on 25 Apr, 2012 04:16 PM

    jimnastiq's Avatar

    I 'm sure i'm removing the same instance (same memory address).

    I'll check right now with a simplier view. And i already remove the view directly within the contextView ( see my 1st post)

  8. 8 Posted by jimnastiq on 25 Apr, 2012 04:30 PM

    jimnastiq's Avatar

    I've checked the onRemove method on my mediator to see if my view is still in the contextView with (view is the injected view in the mediator) :

    if ( contextView.contains(view) )

    and it returns false ...

  9. Support Staff 9 Posted by Ondina D.F. on 25 Apr, 2012 04:35 PM

    Ondina D.F.'s Avatar

    Is it possible to attach your app? I can take a look at it.
    (Make the discussion private until I download the file)

  10. Support Staff 10 Posted by Ondina D.F. on 26 Apr, 2012 06:41 AM

    Ondina D.F.'s Avatar

    In the snippet below, if you don’t set someView to null, it won’t get gc-ed. The reference to SomeView will keep it alive.

    private var someView:SomeView;

    protected function addViewsHandler():void
    {

    someView=new SomeView();
    this.addElement(someView);

    }

    protected function removeViewsHandler():void
    {

    this.removeElement(someView);
    someView =null;

    }

    Let me know if it solves your problem.

  11. 11 Posted by jimnastiq on 26 Apr, 2012 07:25 AM

    jimnastiq's Avatar

    Thx again for your help Ondina!

    I will try to make you a project illustrating the problem.
    And for your last post, as i tell you i'm not keeping reference of the new instance of my view i just create it in the addElement method :

    addElement(new MyView())

    and to remove it i just kept a reference on it somewhere else, and this reference is "cleaned" when i change the view 'cause this properties take the new view instance.

    keep you informed when i post the project ;)

  12. Support Staff 12 Posted by Ondina D.F. on 26 Apr, 2012 07:49 AM

    Ondina D.F.'s Avatar

    Sure, no problem:)

    And for your last post, as i tell you i'm not keeping reference of the new instance of my view i just create it in the addElement method : addElement(new MyView())
    and to remove it i just kept a reference on it somewhere else, and this reference is "cleaned" when i change the view 'cause this properties take the new view instance.

    Yeah, it’s better to post an example, so I can see how you’re handling this reference to the view.

  13. 13 Posted by jimnastiq on 26 Apr, 2012 08:20 AM

    jimnastiq's Avatar

    Ondina,

    you can find attached the mini-project illustrating the problem and a screenshot of profiler showing the occurence of ViewOne.

  14. Support Staff 14 Posted by Ondina D.F. on 26 Apr, 2012 08:26 AM

    Ondina D.F.'s Avatar

    Cool. Downloaded the files. I'll let you know about my findings as soon as possible.

  15. Support Staff 15 Posted by Ondina D.F. on 26 Apr, 2012 09:22 AM

    Ondina D.F.'s Avatar

    I think, I found the culprit. I'll be back soon with explanations

  16. 16 Posted by jimnastiq on 26 Apr, 2012 09:23 AM

    jimnastiq's Avatar

    yeah ! you rocks :)

  17. Support Staff 17 Posted by Ondina D.F. on 26 Apr, 2012 10:34 AM

    Ondina D.F.'s Avatar
    • First thing that I found to be a problem was the Button in ViewOne – btnView. I’m not sure if it has to do with focus, buttonMode or whatever, but it seems to be a bug (??)

    I changed the event listener in ViewOneMediator from
    eventMap.mapListener(view.myLabel, MouseEvent.CLICK, onMouseClick, MouseEvent);
    to
    eventMap.mapListener(view, ViewsEvent.ViewOneOnClick , onViewClick);//a custom event – the name is bad, I know

    but that didn’t solve the problem.

    Then I commented out the button and I added an event listener to the Label’s click.

    • Second thing was the reference to the view in your model, which kept the view alive. So, I did this in the onRemove() of ViewOneMediator:

    viewModel.currentView=null;

    and after that ViewOne got gc-ed!

    I tried to set the view to null in onRemove() as well, but without the 2 other solutions mentioned above it didn’t work.

    Then I added the same logic to ViewTwo and ViewTwoMediator.
    In this scenario viewModel.currentView was replacing the views accordingly, and indeed, it didn’t keep a reference to the previous view.
    Thus, the viewModel.currentView=null; was superfluous.

    So the conclusion is, that the Button is the culprit. Bad, bad Flex Buttons;) I don’t have time to investigate why it is behaving like this and whether it is indeed a bug or not. If you find out what’s wrong, please let us know.

  18. 18 Posted by jimnastiq on 26 Apr, 2012 10:41 AM

    jimnastiq's Avatar

    Thx Ondina,
    could you share your modified project please ? 'cause i've made changed you mentioned (eventmap on label) but the view is still not gc-ed ...

  19. Support Staff 19 Posted by Ondina D.F. on 26 Apr, 2012 10:51 AM

    Ondina D.F.'s Avatar

    Oh, ok. I’ll have to clean it up first, because it’s a mess right now, after the many things I tried.
    On a side note, why aren’t you using a ViewNavigator or something like this, since it’s a mobile app?

  20. Support Staff 20 Posted by Ondina D.F. on 26 Apr, 2012 11:16 AM

    Ondina D.F.'s Avatar

    ViewOneMediator

    
    override public function onRegister( ):void
    {
        eventMap.mapListener(view.someLabel, MouseEvent.CLICK, onMouseClick, MouseEvent); 
        if(contextView.contains(view))
                viewModel.currentView = view;
    }
            
    override public function onRemove():void
    {
        trace("view 1 mediator removed");
        //forcing the gc:
        System.gc();
        System.gc();
        //viewModel.currentView=null;
        //view=null;//good, but not necessary
                
        super.onRemove();
        eventMap.unmapListeners();          
    }
            
    private function onMouseClick(evt:MouseEvent):void
    {           
        viewModel.nextView = "viewTwo";
        viewSignal.dispatch();
    }
    

    I attached the fxp as well. Note: I had to change the Main-app.xml to air 3.2. You’ll have to change it back to 3.1 as it was in your project.

  21. Support Staff 21 Posted by Ondina D.F. on 26 Apr, 2012 11:23 AM

    Ondina D.F.'s Avatar

    Oops, I thought I removed all the files. I’m attaching the clean one again.

  22. Support Staff 22 Posted by Ondina D.F. on 26 Apr, 2012 12:19 PM

    Ondina D.F.'s Avatar

    I can confirm that setting the focusEnabled to false makes it work with the button too.
    Button id="btnView" label="Go To View 2 !!!" focusEnabled="false"
    (focusEnabled is true by default)

  23. 23 Posted by jimnastiq on 26 Apr, 2012 12:24 PM

    jimnastiq's Avatar

    Holly crap !

    I confirm what you said with focusEnabled set to false it's done !

    Now i'll have to check on all my component on my custom view in my big project :)

    Thx again for your time and your help Ondina!

  24. jimnastiq closed this discussion on 26 Apr, 2012 12:24 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac