actionscript-3 - 在 AS3 中为垃圾收集器卸载对象

标签 actionscript-3 flash garbage-collection

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

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

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");
        }
    }
}

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

最佳答案

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

因此,您实际上不需要删除添加到 LoginInterface 的 displayList 中的每个对象。您只需删除您分配的事件监听器即可。

所以,您所做的一切没有任何问题,但您在 unload 方法中真正需要的是:

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

希望有帮助。

关于actionscript-3 - 在 AS3 中为垃圾收集器卸载对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1040268/

相关文章:

flash - 版本中的堆栈溢出错误,但不是调试错误。 ( ActionScript )

java - CreateEntityManagerFactory 的规模正在不断增长。是不是内存泄漏了?

python - 将内存从 Python 释放回操作系统的方法?

java - 次要垃圾收集如何跳过老一代?

css - Apache Flex 4.14.1 BorderContainer Radius 仅适用于 Debugger

android - 如何使用 ActionScript 3 访问 APK 文件中的资源? (土坯空气)

c# - 如何使用 WebClient 登录到 "Flash Website"并使用 c# 下载文件?

apache-flex - Sprite 未接收键盘事件

php - actionscript 3.0 是否强大到足以最终成为我唯一的服务器端语言?

c++ - 具有 WS_EX_LAYERED 窗口样式的 Adob​​e Air