在AS3中卸载垃圾收集器的对象

时间:2022-10-29 01:33:39

I've created an object called loginInterface in flex builder. When this object is initialized it loads the login interface, creating buttons, input boxes and so on.

我在flex builder中创建了一个名为loginInterface的对象。初始化此对象时,它会加载登录界面,创建按钮,输入框等。

I created a method for this object called unload. I also have a method which returns whether the interface has been loaded yet. Now, I want to unload the object so that the screen will not only have space for a new interface but the objects should also really be removed so that that memory can be re-allocated.

我为这个对象创建了一个名为unload的方法。我还有一个方法,它返回接口是否已加载。现在,我想卸载对象,以便屏幕不仅有新的接口空间,而且还应该删除对象,以便可以重新分配该内存。

The loginInterface.as class file:

loginInterface.as类文件:

package
{
    //import required libraries
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.net.navigateToURL;

    public class LoginInterface extends Sprite
    {
        private var welcomeLabel:CustomLabel;
        private var versionLabel:CustomLabel;
        private var loginButton:CustomButton;
        private var registerButton:CustomButton;
        private var usernameLabel:CustomLabel;
        private var passwordLabel:CustomLabel;
        private var usernameInputBox:CustomInputBox;
        private var passwordInputBox:CustomInputBox;
        private var loaded:Boolean = false;

        public function LoginInterface()
        {
            trace("LoginInterface object loaded.");
            init(); //initialize the login interface
        }

        public function init():void //initialize the login interface
        {
            trace("LoginInterface init method was called.");

            //create objects
            welcomeLabel = new CustomLabel(200, 100, 500, 30, "Welcome to the ALPHA client."); //welcome label
            versionLabel = new CustomLabel(200, 120, 500, 30, "Version: v1.0.000", "Arial", 0x000000, 12); //version label
            loginButton = new CustomButton(300, 300, 100, 30, "Login"); //login button
            registerButton = new CustomButton(400, 300, 100, 30, "Register") //register button          
            usernameLabel = new CustomLabel(200, 200, 200, 30, "username: "); //username label      
            passwordLabel = new CustomLabel(200, 240, 200, 30, "password: "); //password label
            usernameInputBox = new CustomInputBox(300, 200, 200, 30, false, 0x6D7B8D); //username input box
            passwordInputBox = new CustomInputBox(300, 240, 200, 30, true, 0x6D7B8D); //password input box

            //add objects to the display tree
            addChild(welcomeLabel);
            addChild(versionLabel);
            addChild(loginButton);
            addChild(registerButton);
            addChild(usernameInputBox);
            addChild(usernameLabel);
            addChild(passwordInputBox);
            addChild(passwordLabel);

            //register object events
            registerButton.addEventListener(MouseEvent.CLICK, registerClicked); //register button is clicked
            loginButton.addEventListener(MouseEvent.CLICK, loginClicked); //login button is clicked

            //interface has been loaded
            loaded = true;
        }

        public function isLoaded():Boolean
        {
            if (loaded) return true;
            return false;
        }

        public function unload():void
        {
            if (!loaded) return;
            //welcomeLabel
            removeChild(welcomeLabel);
            welcomeLabel = null;
            //versionLabel
            removeChild(versionLabel);
            versionLabel = null;
            //loginButton
            loginButton.removeEventListener(MouseEvent.CLICK, loginClicked);
            removeChild(loginButton);
            loginButton = null;
            //registerButton
            registerButton.removeEventListener(MouseEvent.CLICK, registerClicked);
            removeChild(registerButton);
            registerButton = null;
            //usernameInputBox
            removeChild(usernameInputBox);
            usernameInputBox = null;
            //usernameLabel
            removeChild(usernameLabel);
            usernameLabel = null;
            //passwordInputBox
            removeChild(passwordInputBox);
            passwordInputBox = null;
            //passwordLabel
            removeChild(passwordLabel);
            passwordLabel = null;
            //set loaded to false
            loaded = false;
        }

        private function loginClicked(event:MouseEvent):void
        {
            trace("Login button has been clicked.");
            var username:String = usernameInputBox.text;
            var password:String = passwordInputBox.text;
            if (!checkLogin(username, password)) {
                new Alert("Please enter a correct username and password.");
            }
            else {
                trace("Creating socket connection.");
                var socketConnection:SocketConnection = new SocketConnection(this);
            }
        }

        private function checkLogin(username:String, password:String):Boolean
        {
            if ((username == "") || (password == "")) {
                return false;
            }
            return true;
        }

        private function registerClicked(event:MouseEvent):void
        {
            trace("Register button has been clicked.");
            var url:URLRequest = new URLRequest("http://url.com/client/register.php");
            navigateToURL(url, "_blank");
        }
    }
}

Please see the init function where the objects are loaded and the unload function where they should be unloaded. This, visually, works. Is it however the best way to do it - and does it even make these objects unload from memory by the garbage collector after a while?

请参阅加载对象的init函数和卸载它们的卸载函数。这在视觉上是有效的。然而,它是最好的方法 - 并且它甚至会在一段时间后通过垃圾收集器从内存中卸载这些对象吗?

2 个解决方案

#1


When you remove an object (such as LoginInterface) from its parent's displayList, all of the children inside of that object will be automatically removed from memory, as well, as long as there are no other objects that contain references to the children.

当您从其父级的displayList中删除一个对象(例如LoginInterface)时,该对象内的所有子级也将自动从内存中删除,只要没有其他对象包含对子级的引用即可。

So, you don't actually need to remove each of the objects you add to LoginInterface's displayList. You just need to remove the event listeners that you assigned.

因此,您实际上不需要删除添加到LoginInterface的displayList中的每个对象。您只需要删除您指定的事件侦听器。

So, there's nothing wrong with what you've got going, but all you really need in your unload method is:

所以,你已经完成了什么并没有错,但你在卸载方法中真正需要的是:

loginButton.removeEventListener(MouseEvent.CLICK, loginClicked);
registerButton.removeEventListener(MouseEvent.CLICK, registerClicked);

Hope that helps.

希望有所帮助。

#2


You unloading code will work as you intend it to. The Flash garbage collector uses reference counting to determine whether a particular object is a candidate for being garbage collected. After running your unload() function all of the CustomButton objects you created in load() will have a reference count of 0 and will eventually be garbage collected.

卸载代码将按照您的意图运行。 Flash垃圾收集器使用引用计数来确定特定对象是否是垃圾收集的候选对象。运行unload()函数后,在load()中创建的所有CustomButton对象的引用计数都为0,最终将被垃圾回收。

#1


When you remove an object (such as LoginInterface) from its parent's displayList, all of the children inside of that object will be automatically removed from memory, as well, as long as there are no other objects that contain references to the children.

当您从其父级的displayList中删除一个对象(例如LoginInterface)时,该对象内的所有子级也将自动从内存中删除,只要没有其他对象包含对子级的引用即可。

So, you don't actually need to remove each of the objects you add to LoginInterface's displayList. You just need to remove the event listeners that you assigned.

因此,您实际上不需要删除添加到LoginInterface的displayList中的每个对象。您只需要删除您指定的事件侦听器。

So, there's nothing wrong with what you've got going, but all you really need in your unload method is:

所以,你已经完成了什么并没有错,但你在卸载方法中真正需要的是:

loginButton.removeEventListener(MouseEvent.CLICK, loginClicked);
registerButton.removeEventListener(MouseEvent.CLICK, registerClicked);

Hope that helps.

希望有所帮助。

#2


You unloading code will work as you intend it to. The Flash garbage collector uses reference counting to determine whether a particular object is a candidate for being garbage collected. After running your unload() function all of the CustomButton objects you created in load() will have a reference count of 0 and will eventually be garbage collected.

卸载代码将按照您的意图运行。 Flash垃圾收集器使用引用计数来确定特定对象是否是垃圾收集的候选对象。运行unload()函数后,在load()中创建的所有CustomButton对象的引用计数都为0,最终将被垃圾回收。