ItemStatusView 클래스에 EquipBtn 변수가 있고 해당 Button변수에 컨트롤러에 있는 데이터를 인자값으로 받아와 이벤트를 등록해놨는데 이때 인자값의 초기값은 null값으로 설정이 되있었다.
ItemSlot 클래스에 버튼을 눌러 Item 데이터를 컨트롤러로 보내 초기화를 하였기에 null값은 사라졌다고 생각했다
왜냐하면 Class는 참조값이기에 변경될것이기 때문이다),
그리고 실제로 콘솔창에서는 null값이 들어온다고 오류가 발생하였다.
원인은 item이 참조형 변수라고 해도, 이 참조가 유효하려면 메모리 상의 객체를 가리키고 있어야 하는데 이미 처음 초기값을 null로 설정 한 뒤였고, 해당 변수는 다른 클래스(ItemStatusView)로 넘어가 있는 상태였기에 아무리 Controller에서 item이 초기화가 되더라도 view에서 받는 이벤트의 인자값은 null이 들어오는 것이였다.
즉, 이 문제를 일으킨 이유는
null 이 빈 데이터라고만 착각을 해버려서 발생한 문제였다.
null은 빈데이터가 아닌 주소값이 없다라는 의미이기 떄문이다.
C++에서는 포인터 개념이 있기에 주소값 및 할당을 하게되면 무조건 해제를 해야만하지만
C#을 계속 사용하다보니 주소값에 대해서 깜빡했던것 같다.
C#은 포인터 개념이 없기 때문에 자동으로 Heap영역에 알아서 할당이 되었기 때문에 간단히 생각을 했던것이다.
대처법으로는 View의 버튼 변수를 프로퍼티로 선언한뒤 호출하여 Controller에서 이벤트를 등록하였다.
public class ItemStatusController : UIController
{
public ItemSlot SelectItem;
private ItemStatusModel itemStatusModel;
private ItemStatusView itemStatusView;
public override void Initialize(IUIBase view, UIModel model)
{
itemStatusModel = model as ItemStatusModel;
itemStatusView = view as ItemStatusView;
base.Initialize(itemStatusView, itemStatusModel);
//아이템 장착 버튼 이벤트 함수 등록 (장착 , UI 출력)
itemStatusView.EquipButton.onClick.AddListener(() => GameManager.Instance.player.EquipItem(SelectItem.item));
itemStatusView.EquipButton.onClick.AddListener(() => OnShow());
//아이템 장착해제 버튼 이벤트 함수 등록 (장착해제 , UI 출력)
itemStatusView.DisEquipButton.onClick.AddListener(() => GameManager.Instance.player.DisEquipItem());
itemStatusView.DisEquipButton.onClick.AddListener(() => OnShow());
}
}
public class ItemStatusView : MonoBehaviour, IUIBase
{
[SerializeField] private TextMeshProUGUI curUpgradeLevelText;
[SerializeField] private TextMeshProUGUI maxUpgradeLeveText;
[SerializeField] private TextMeshProUGUI UpgradeCostText;
[SerializeField] private TextMeshProUGUI itemPassiveEffectText;
[SerializeField] private TextMeshProUGUI itemEquipEffectText;
[SerializeField] private Image ItemIcon;
[SerializeField] private Button UpgradeBtn;
[SerializeField] private Button EquipBtn;
[SerializeField] private Button DisEquipBtn;
public Button EquipButton { get => EquipBtn; }
public Button DisEquipButton { get => DisEquipBtn; }
public Button UpgradeButton { get => UpgradeBtn; }
}
이런식으로 사용하니, 우선 item은 null값이 들어가있는 상태에서 외부에서 데이터가 초기화 되더라도
Controller 클래스 안에 멤버변수로 되어있으니 참조값을 제대로 활용 할 수 있게 되었다.