2012-06-14 2 views
0
public class MyButton extends Sprite 
{  
    public function MyButton(defaultHandler:Function)  
    {  
     addEventListener(MouseEvent.CLICK, defaultHandler);  
    } 
} 

// Основной классAS3: Это может вызвать утечку памяти?

var myButton:MyButton =new MyButton(someFunction); 
addChild(myButton) 

removeChild(myButton); 
myButton = null; 

IE Я добавляю функцию обработчика событий анонимного Mouseclick изнутри мой класс Button, когда он построен, и конкретно не удаляя его, когда он удаляется со сцены и изгнан.

Будет ли этот объект иметь право на сборщик мусора, не будет ли это причиной утечки памяти? Или с того, что прослушиватель событий ссылался только на объект, который был удален, будет ли он также удален?

ответ

1

Слушатель событий на экземпляре Button предотвратит сбор мусора, если вы специально не удалите слушателя или не сообщите, что слушатель будет слабым эталоном.

addEventListener(MouseEvent.CLICK, defaultHandler, false, 0, true); 

Последний аргумент true, передается для параметра useWeakReference. Из docs:

useWeakReference: Boolean (по умолчанию = FALSE) - Определяет, является ли ссылка на слушатель сильная или слабая. Сильная ссылка ( по умолчанию) не позволяет вашему слушателю быть собранным мусором. A слабый ссылка нет.

+0

При установке слушателя, как слабые, ответственность за это удаление передается сборщику мусора. Вы никогда не должны доверять GC, так как это в основном случайное, так что это может занять некоторое время. Слабые слушатели - для ленивых разработчиков, которые не берут на себя ответственность за очистку собственного кода. Единственным исключением могут быть исполнители событий на сцене, но вы всегда должны удалять слушателей самостоятельно. –

+1

Согласовано @MarkKnol, и я всегда удаляю их явно.Говоря это, это не то, о чем спрашивает ОП. – sberry

+0

Я нашел это, хотя это немного другой сценарий, но с аналогичной проблемой: http://stackoverflow.com/questions/8471578/would-this-code-cause-memory-leakage , у которого есть цитата : «Слушатели событий не удаляются автоматически из памяти, потому что сборщик мусора не удаляет слушателя **, пока существует объект диспетчеризации ** (если параметр useWeakReference не установлен в true)». - поэтому в соответствии с этим, ЕСЛИ объект, на который ссылаются слушатели **, больше не существует, он не должен ** сохраняться и не должен вызывать утечку - может ли это подтвердить это? –

1

В то время как точки в ответе @ sberry полностью действительны, более подробно рассмотрите, какие объекты имеют ссылки друг на друга в этом сценарии.

Если основной класс вокруг в течение всего срока применения, есть память не утечка:

Основной класс имеет ссылку на класс кнопки, что она инстанцированная.

Класс кнопки имеет ссылку на основной класс, начиная с функции обработки событий.

Главный класс отключает ссылку на кнопку.

На данный момент есть ссылки на кнопку. Кнопка может и будет собираться мусором.

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

PS: Я не спорю против удаления слушателей событий, когда и с помощью слабых ссылок, я оба этих практиков себя как можно больше :)

+0

Да, это то, о чем я говорил, что если сам объект больше не существует, то в теории ни один из них не должен прослушивать его событие. - Кто-нибудь может это подтвердить? –

+0

[Вот статья из Adobe] (http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html), которая поддерживает то, что я говорю. Сбор мусора работает двумя способами: подсчет ссылок (быстрый), а затем «отметка и развертка» захватывает материал с круговыми ссылками (где счетчик никогда не переходит в 0). В вашем примере счетчик ссылок для кнопки переходит в 0, когда вы делаете: 'removeChild (myButton); myButton = null; кнопка становится пригодной для сбора мусора, но нет никакой гарантии, когда это произойдет. –

+0

Чтобы уточнить и ответить на конкретный вопрос в вашем комментарии: при использовании 'addEventListener()' в кнопке кнопка в основном отображает это событие в функцию (определенную в вашем основном классе в этом случае). Поэтому, когда кнопка получает g/c'd, это сопоставление идет с ней, и слушатель событий может считаться более не существующим. По-прежнему хорошей практикой является удаление слушателей и/или использование слабых ссылок при их добавлении :) –

Смежные вопросы