문제 상황
Unity에서 for문을 통해 UI 버튼에 이벤트 리스너를 등록하던 중 내가 생각한 값이 아니라 이상한 값이 들어가는 현상이 생
겼다. 코드상에서 원인을 찾을 수 없어서 중단점을 통해 확인해보니 메서드에 전달해준 인자 값이 계속 증가한다는 것을 확인 했다.
해당 문제를 해결하기위해 구글링을 통해서 자료를 찾아보니 람다식은 인자를 참조 해서 그 문제가 생긴다는 것을 알았다.
문제 코드
for (int i = 0; i < 10; i++)
{
button.onClick.AddListener(() => SomeMethod(i));
}
AddListenr를 통해 인자 값을 넘겨줄 때는 람다식 혹은 델리게이트를 사용해 넘겨줘야하는데 람다식과 델리게이트 모두
참조형으로 값을 가지고 있기 때문에 문제가 발생했다.
해결 코드
for (int i = 0; i < 10; i++)
{
int index = i;
button.onClick.AddListener(() => SomeMethod(index));
}
문제의 원인은 람다식이나 델리게이트가 i값을 참조하고 있는데, for문에서 i 값이 계속 변경되기 때문이었다. 클릭 이벤트는 for문 반복이 완료된 후 발생하기 때문에 모두 동일한 i값을 참조하고 있던 것 이다.
해결 방법은 의외로 간단했다. i값을 바로 람다식에 넣어주는 것이 아니라 값 형의 지역 변수에 넣고 이를 람다식에 넣어주는 것이었다. 선언된 index 지역 변수는 값 형이기 때문에 한 번 설정된 값은 변경되지 않는다. 따라서 람다식이나 델리게이트가 index를 참조할 때, 고정된 값을 참조하게 되므로 원하는 i 값을 전달할 수 있게 됐다.
마무리
for문을 통해 이벤트 리스너를 등록할 때 인자 값이 동일해지는 이유는 람다식이나 델리게이트가 변수 i를 참조 형태로 저장하기 때문이었다. 이를 방지하기 위해서는 for문 내부에서 새로운 값형 지역 변수를 선언하여 고정된 값을 참조하도록 코드를 수정하면 된다.
'내일배움캠프' 카테고리의 다른 글
내일배움캠프: 유니티 Character Controller (0) | 2024.11.11 |
---|---|
내일배움캠프: object와 generic (0) | 2024.11.08 |
내일배움캠프: 이벤트 버스 패턴 (Event Bus Pattern) (0) | 2024.11.02 |
내일배움캠프: 유니티 JsonUtility을 활용한 데이터 저장 및 불러오기 (0) | 2024.11.01 |
내일배움캠프: 코루틴을 사용한 지속 회복 포션 구현 (2) | 2024.11.01 |