event, Action은 꽤 많이 사용하는 편인데
가끔씩 초기화 코드가 중복되면서 이벤트가 중복 호출되는 문제가 발생하기 쉽다.
그런데 이런 휴먼에러가 발생하면 이벤트 쪽은 이원화되어 있기 떄문에 오류를 발견하기 어렵다..
1. 방법 1 : 명시적으로 제거하기
using System.Linq;
private EventHandler foo;
public event EventHandler Foo
{
add
{
if (foo == null || !foo.GetInvocationList().Contains(value))
foo += value;
}
remove
{
foo -= value;
}
}
2. 방법 2 : 언제나 초기화 전에 제거하기
중요한 사실. -=은 발견되지 않아도 예외가 발생하지 않는다.
때문에 많은 개발자들이 체인을 걸기 전에 빼는 방식으로 구현한다고 함.
private void OnEnable()
{
Value.onValueChanged -= OnValueCallback;
Value.onValueChanged += OnValueCallback;
}
private void OnDisable()
{
Value.onValueChanged -= OnValueCallback;
}
다음과 같이 이벤트 핸들러 내부에서 처리하는 방법도 존재한다!
private EventHandler _foo;
public event EventHandler Foo
{
add
{
_foo -= value;
_foo += value;
}
remove
{
_foo -= value;
}
}
3. 단일 이벤트라면 그냥 대입연산자 쓰기
- 다른 이벤트가 체인될게 아니라면 그냥 대입연산자를 써버리는 방법도 있다.
연결되어있던 모든 이벤트들의 레퍼런스가 사라지며, 새로 대입한 레퍼런스로 바뀐다.
- 버튼은 일반적으로 한 개의 이벤트만 가지기 때문에, 주로 버튼에 이벤트 체인걸 때 사용하게 된다.
private void OnEnable()
{
Value.onValueChanged = OnValueCallback;
}
private void OnDisable()
{
Value.onValueChanged -= OnValueCallback;
}
마치며..
사실 이벤트 order를 가진 프로퍼티를 만들어볼까 하고 만지작거리고 있었는데,
이벤트는 이원화되어야하며, 순서를 가진다면 당신은 무언가 잘못 짠 것입니다.
라길래 순서 없는 버전까지만 하는걸로!
반응형
'게임엔진(GameEngine) > Unity3D' 카테고리의 다른 글
OnPhotonInstantiate, STart OnPhotonSerializeView 순서 (0) | 2022.02.11 |
---|---|
PhotonNetwork.Instantiate with data (0) | 2022.02.10 |
SendMessage(.. SendMessageOptions.RequireReceiver) 수신자를 찾을수 없을때 경고) (0) | 2022.02.01 |
PlayerPrefs를 활용한 데이터 로드/저장 (0) | 2022.01.31 |
Android SDK does not include your Target SDK of 28 (0) | 2022.01.15 |