[Unity]반복문에서 람다,delegate함수 사용시 문제점(클로저 문제)

jh Seo·2022년 8월 25일
0

유니티

목록 보기
9/50

개요

     for(int i=0;i<buttonButtons.Length;i++)
        {
            //tutorial이 3번씬부터 시작이므로
            buttonButtons[i].onClick.AddListener(delegate { loadGame(i+3); });
        }

buttonButtons에 getcomponentsinchildren()함수를 사용해 버튼들을 다 넣어준 후,

반복문,delegate함수를 통해 각각 버튼에 onClick.AddListener함수로
loadGame함수를 넣어주려했으나 먹통이 되었다.

클로저 문제

이유는 반복문을 통해 람다함수나 delegate함수를 사용하게 되면 생기는
클로저(closure) 문제라는 것이였다.

클로저란 내부 클래스에 정의한 변수를 람다함수가 사용하게되는 걸 말하는 데
이런 방식의 문제점은 코드에서 보면

     for(int i=0;i<buttonButtons.Length;i++)
        {
            //tutorial이 3번씬부터 시작이므로
            buttonButtons[i].onClick.AddListener(delegate { loadGame(i+3); });
        }

람다함수가 i를 참조하는데 여기서 i값의 복사값을 사용하는 것이 아니라
i변수 그 자체를 참조하게 되고, 반복문이 다 끝난 후 i값을 참조하게 된다.
따라서 위와같은 상황에선 i가 buttonButtons.Length값일 때 참조된다.

해결 방법

따라서 i값이 아닌 매 반복문마다 새로 선언되는 값을 하나 지정해서
그 값을 참조하게 짜면 해결된다.

     for(int i=0;i<buttonButtons.Length;i++)
        {
            int temp = i;
            //tutorial이 3번씬이므로
            buttonButtons[temp].onClick.AddListener(delegate { loadGame(temp+3); });
        }

생각

람다함수를 별로 접해본 적이 없다보니 처음 들은 개념이다.
앞으로는 람다함수에 가변적인 변수를 사용할 땐 주의해야겠다.

profile
코딩 창고!

0개의 댓글