所有事物都继承了相同的类,但其中一些不按预期工作。

huangapple go评论68阅读模式
英文:

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&lt;BasePanel&gt; stackPanels;

then I have different panels all inherited BasePanel.
inside they all have a method call

public virtual void OnExit()
    {
        Debug.Log(&quot;UITypeName= &quot;+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&lt;Button&gt;(&quot;Next&quot;).onClick.AddListener(() =&gt;
        {
            //Debug.Log($&quot;Start create account&quot;);
     
            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&lt;Button&gt;(&quot;SelectFile&quot;).onClick.AddListener(()=&gt;
        {
        Debug.Log(&quot;Upload&quot;);
        PanelManage.Pop();
            
        });
        UITool.GetOrAddComponentsInChildren&lt;Button&gt;(&quot;UploadLater&quot;).onClick.AddListener(() =&gt;
        {
            //Debug.Log($&quot;UploadLater&quot;);
            
           PanelManage.Pop();
           PanelManage.Push(new IntroductionPanel());
          // Debug.Log(PanelManage.panel.UIType.Path);
        
           
        });
    }

POP

public void Pop()
    {
        if (stackPanels.Count &gt; 0)
        {
            stackPanels.Peek().OnExit();
            Debug.Log(stackPanels.First());
            //Debug.Log(stackPanels.First().UIManage);
            stackPanels.Pop();
       
        }
            
        if (stackPanels.Count &gt; 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(&quot;UITypeName= &quot;+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.

huangapple
  • 本文由 发表于 2023年2月8日 16:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383081.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定