Prenons l’exemple d’un script qui ajoute un callback sur un bouton :
Button _button;
int _number = 0;
void Start()
{
_button = GameObject.Find("Button");
_button.onClick.AddListener(() => {
_number++;
Debug.Log(_number);
});
}
// On click:
// 1
// 2
// 3...
Ici, l’expression capture la variable _number
, faisant d’elle une closure. Si on clique sur le bouton 3 fois, _number
sera égal à 3. Jusque la, tout va bien. Maintenant si on détruit MyBehaviour.cs
, que l’on crée une nouvelle instance et que l’on clique sur le bouton, _number
sera égal à 4, alors que la valeur attendue est 1.
La variable _number
capturée existe toujours en mémoire, car référencée par la fonction anonyme.
Solution
La solution est plutôt simple, il faut détruire toutes les références restantes. Ici il suffit de détruire les delegates du bouton :
Button _button;
int _number = 0;
void Start()
{
_button = GameObject.Find("Button");
+ _button.onClick.RemoveAllListeners();
_button.onClick.AddListener(() => {
_number++;
Debug.Log(_number);
});
}