英文:
All things inherited the same class, but some of them dont work as excepted
问题
我有一个堆栈来存储所有继承自BasePanel类的对象。
private Stack<BasePanel> stackPanels;
然后我有不同的面板,它们都继承自BasePanel。在这些面板内部,它们都有一个叫做OnExit的方法。
public virtual void OnExit()
{
Debug.Log("UITypeName= " + UIType.Name);
UIManage.DestoryUI(UIType);
}
然后我在堆栈中的第一个对象中触发了OnExit方法。
public override void OnEnter()
{
UITool.GetOrAddComponentsInChildren<Button>("Next").onClick.AddListener(() =>
{
//Debug.Log("Start create account");
PanelManage.Pop();
PanelManage.Push(new PrefectProfile());
});
}
第一个面板运行正常,退出也正常,但是第二个面板没有退出。
public override void OnEnter()
{
UITool.GetOrAddComponentsInChildren<Button>("SelectFile").onClick.AddListener(() =>
{
Debug.Log("Upload");
PanelManage.Pop();
});
UITool.GetOrAddComponentsInChildren<Button>("UploadLater").onClick.AddListener(() =>
{
//Debug.Log("UploadLater");
PanelManage.Pop();
PanelManage.Push(new IntroductionPanel());
// Debug.Log(PanelManage.panel.UIType.Path);
});
}
POP方法:
public void Pop()
{
if (stackPanels.Count > 0)
{
stackPanels.Peek().OnExit();
Debug.Log(stackPanels.First());
//Debug.Log(stackPanels.First().UIManage);
stackPanels.Pop();
}
if (stackPanels.Count > 0)
stackPanels.Peek().OnResume();
}
问题出在,代码是逐行运行的。如果你看控制台输出的日志:create panel和perfect profile,这些来自于POP方法,如果它确实运行了Debug,那么它也应该运行了上面的代码,也就是OnExit。然而,当你看控制台时,只有在create panel时才会运行OnExit方法,因为它调试了Debug.Log("UITypeName= " + UIType.Name);
,但在PrefectPanel中没有运行。而它们都继承自同一个基类,意味着方法是一样的。那么为什么在第二个面板上没有运行,但在第一个面板上却正常运行呢?如果它没有运行Exit方法,为什么会有Debug输出的名字?因为Debug位于Exit方法下方,如果有任何错误,它应该已经弹出来了。但是,假设它确实运行了Exit方法,为什么它没有销毁面板,而且第二个面板上也没有退出日志?我已经检查了代码几个小时,但是没有任何线索。
英文:
I have a stack to store all objects with base panel class
private Stack<BasePanel> stackPanels;
then I have different panels all inherited BasePanel.
inside they all have a method call
public virtual void OnExit()
{
Debug.Log("UITypeName= "+UIType.Name);
UIManage.DestoryUI(UIType);
}
Then I trigger the Onexit method in the object using the first object in the stack.
public override void OnEnter()
{
UITool.GetOrAddComponentsInChildren<Button>("Next").onClick.AddListener(() =>
{
//Debug.Log($"Start create account");
PanelManage.Pop();
PanelManage.Push(new PrefectProfile());
});
}
The First panel is working fine and exit like except however the second panel didn't get exit.
public override void OnEnter()
{
UITool.GetOrAddComponentsInChildren<Button>("SelectFile").onClick.AddListener(()=>
{
Debug.Log("Upload");
PanelManage.Pop();
});
UITool.GetOrAddComponentsInChildren<Button>("UploadLater").onClick.AddListener(() =>
{
//Debug.Log($"UploadLater");
PanelManage.Pop();
PanelManage.Push(new IntroductionPanel());
// Debug.Log(PanelManage.panel.UIType.Path);
});
}
POP
public void Pop()
{
if (stackPanels.Count > 0)
{
stackPanels.Peek().OnExit();
Debug.Log(stackPanels.First());
//Debug.Log(stackPanels.First().UIManage);
stackPanels.Pop();
}
if (stackPanels.Count > 0)
stackPanels.Peek().OnResume();
}
So the logic is OnEnter -> so button will respone-> then pop-> pop trigger OnExit.
The part I don't get is, that the code is run line by line. And if you see the console where it debugs: create panel and perfect profile, these come from POP, if it did run the Debug meaning it run the code above as well, which is OnExit.
However, when you look at the console, OnExit only gets run in the create panel since it debugs Debug.Log("UITypeName= "+UIType.Name);
But it didn't run for the PrefectPanel. And they both have the same inherited class meaning the method are the same. Then how come it didn't get run on the second panel but it work on the first one? And if it didn't run the Exit method, how come it has the Debuged name? Since the Debug is below the Exit method, if there's any error it should pop up already. However, let's say it did run the Exit method then how come it didn't destroy the panel and no log for the exit on the second panel? I have been checking the code for hours and do not have any clues
答案1
得分: 1
你的重写没有调用基本实现 => 你只能通过新的实现完全替代它们!在override
中添加以下调用:
base.OnEnter();
并相应地
base.OnExit();
根据你的需求。参考例如base
关键字示例
基本上可以放在任何地方,但通常我会选择以下方式:
public override void OnEnter()
{
base.OnEnter();
// 额外的自定义实现
}
public override void OnExit()
{
// 额外的自定义实现
base.OnExit();
}
这样可以确保首先运行基本初始化,但在拆卸时使其成为最后一个,因为在你的情况下,在销毁事物之后,自定义实现可能不再有效,因为引用可能已经丢失等等。
英文:
Your overrides are not calling the base implementation => you only fully replace them by the new implementation!
Within the override
ones add calls to
base.OnEnter();
and accordingly
base.OnExit();
according to your needs.
See e.g. base
keyword examples
It basically can be anywhere but usually I would go with
public override void OnEnter()
{
base.OnEnter();
// additional custom implementation
}
public override void OnExit()
{
// additional custom implementation
base.OnExit();
}
in order to let the initialization of the base run first but when tearing down make it the last since e.g. in your case after destroying things the custom implementation might not be valid anymore since references might be already gone etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论