Выгрузка объектов для сборщика мусора в AS3 - PullRequest
2 голосов
/ 24 июня 2009

Я создал объект с именем loginInterface во Flex Builder. Когда этот объект инициализируется, он загружает интерфейс входа в систему, создает кнопки, поля ввода и т. Д.

Я создал метод для этого объекта, который называется unload. У меня также есть метод, который возвращает, был ли интерфейс уже загружен. Теперь я хочу выгрузить объект, чтобы на экране было не только место для нового интерфейса, но и объекты должны быть действительно удалены, чтобы можно было перераспределить память.

Файл класса 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, где они должны быть выгружены. Это, визуально, работает. Однако это лучший способ сделать это - и заставляет ли он эти объекты выгружаться из памяти сборщиком мусора через некоторое время?

Ответы [ 2 ]

2 голосов
/ 25 июня 2009

Когда вы удаляете объект (такой как LoginInterface) из displayList его родителя, все дочерние элементы внутри этого объекта также будут автоматически удаляться из памяти, если нет других объектов, которые содержат ссылки на дочерние элементы .

Таким образом, вам на самом деле не нужно удалять каждый из объектов, которые вы добавляете в displayList LoginInterface. Вам просто нужно удалить назначенные вами прослушиватели событий.

Итак, нет ничего плохого в том, что вы делаете, но все, что вам действительно нужно в вашем unload методе, это:

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

Надеюсь, это поможет.

1 голос
/ 24 июня 2009

Выгрузка кода будет работать так, как вы намереваетесь. Flash-сборщик мусора использует подсчет ссылок, чтобы определить, является ли конкретный объект кандидатом на сборку мусора. После запуска функции unload () все объекты CustomButton, созданные вами в load (), будут иметь счетчик ссылок 0 и в конечном итоге будут собираться мусором.

...