2025. 12. 15. 22:51ㆍ본 캠프
지난번 EventBus를 도입할 때 C#의 라이브러리 클래스인 WeakReference를 통해 강한참조를 약한참조로 바꾸면서
콜백을 감싸는 작업을 했었다.
오늘 UI간의 연결을 진행했을 때 문제가 생겼었는데
GC가 초기화 시점에 바로 수거해버려서 구독자에게 이벤트가 전달이 안되는 현상이 있었다.

그래서 구독자가 이벤트를 내부에서 '강한참조' 형태로 필드를 저장해놓고
해당 이벤트를 활용하는 방식으로 구현했는데
EventBus(static)은 구독자를 강하게 붙잡았을 때 메모리 누수가 생기게 된다.
이벤트 버스가 구독자 생명주기를 소유하지는 않게 하면서 유령호출이나 Destory, Additive Scene 언로드, 비활성/활성 전환 등
static 이벤트가 구독자를 붙잡으면 GC가 회수를 못하게 된다.
C#에서는 메서드 그룹을 넘기면 Delegate 인스턴스를 만드는데
이 Delegate안에는 (Target(this)와 Method(메서드 포인터)를 가진 힙 객체가 된다
이 델리게이트 객체를 어디에서도 강하게 참조하지 않으면 GC에서 도달 불가능으로 취급하게 된다.
그래서 EventBus가 WeakReference로만 Delegate를 잡으면 GC 대상이 되면서 어느 순간 수거하게 되고
결국 발행시점에서 TryGetTarget에 실패 해 구독자가 호출을 못하게 되는 현상이 생긴다.
이렇게되면 OnEnable 시점에 로그는 뜨지만 이벤트 수신은 안되는 이상한 현상이 생기게 된다.
그래서 구독자가 필드로 들고있게 되면 구독자가 살아 있는 동안만 Delegate가 유지되게 하는 수명주기를 만들 수 있게 된다.
WeakReference는 생명 유지를 해주지 않기 때문에 구독자 쪽에서 꼭 필드로 저장해야 올바른 이벤트 수신이 된다.
왜 런타임 이후 버튼을 바로 눌러도 패널이 안뜨는 걸까?


UI 작업하다보니 버튼에 기능을 추가하다가 이상한 점을 발견했는데
런타임 이후 처음 클릭 시에만 버튼이 해당 기능을 구현하지 못하다가 다시 재차 클릭하면 패널을 띄우게 되는 현상이 있었다.
디버그 로그는 정상적으로 출력되고 있음에도 패널은 안켜지는 이상한 상황이었는데
알고보니 Awake 단에서 내가 gameObject.SetActive(false)를 추가해놔서 이런 현상이 있었다.
왜 이런 문제가 생긴걸까?

Awake 단에서 SetActive를 쓰게 되면 Hierachy 상의 UI 초기화 순서가 깨지게 되면서 이런일이 생긴다.
그래서 inspector 상으로 조절해주고 Awake에서 강제로 Active제어를 하는 일은 최대한 없어야 한다는 걸 알게 됐다.
'본 캠프' 카테고리의 다른 글
| [내일배움캠프 본 캠프 57일차] UI작업_RawImage (0) | 2025.12.17 |
|---|---|
| [내일배움캠프 본 캠프 56일차] UI작업_Additive Scene (0) | 2025.12.16 |
| [내일배움캠프 본 캠프 54일차] 사물을 확대해서 돌려보기_1 (0) | 2025.12.12 |
| [내일배움캠프 본 캠프 53일차] 볼륨/비네팅 DOTween (0) | 2025.12.11 |
| [내일배움캠프 본 캠프 52일차] 이벤트버스 구성 (0) | 2025.12.10 |