【问题标题】:Is this exception due to garbage collection?这个异常是因为垃圾收集吗?
【发布时间】:2014-03-08 02:43:20
【问题描述】:

我在以下代码的第 89 行遇到了一个奇怪的异常:

    private byte   state = 0;
    .
    .
    .

    void OnGUI(){
    int i;
    GUI.skin = skin;
    GUI.skin.box.fontSize = 25;
    GUI.skin.label.fontSize = 18;
    if(state==0){           
        GUI.skin.font = system;
        GUIContent tA = new GUIContent("A");
        Vector2 tz = GUI.skin.label.CalcSize(tA);
        GUI.skin.label.CalcHeight(tA,tz.x);
        height = (byte) tz.y;
        rows   = (byte) (Screen.height/height);
        mark   = 0;
70      view   = new Log[rows];
        for(i=0;i<rows;i++){
72          view[i] = new Log();
            if(vis.ValidRow()){
74              mark++;
75              view[i].time = vis.time;
76              view[i].descrip = vis.descrip;
                vis.Next();
            }
        }
        state = 1;
    }

    GUI.skin.font = chrome;
    GUI.Box(new Rect(0,0,Screen.width,50),"Server");
    GUI.color = Color.green;
    GUI.skin.font = system;
    short y = 50;
    for(i=0;i<mark;i++){
89      GUI.Label(new Rect(10,y,200,height),String.Format("{0:yyyy/MM/dd HH:mm:ss}",view[i].time));
        GUI.Label(new Rect(220,y,Screen.width-260,height),view[i].descrip);
        y += height;
    }
}

System.NullReferenceExeption 被抛出,由于 view 为空,但我不知道为什么。除了 view 之外,所有变量都具有正确的值。在这种情况下state1,这意味着if里面的代码被执行了,mark3,表示行:707274执行没有问题。如果由于某种原因 new 在第 70 行失败,异常将在 72 行被抛出。我说的对吗?...但是 7576 行也被毫无问题地执行了。

对于这种行为,我能找到的唯一合理解释是 view 被垃圾收集了,但不明白为什么......如果是这样,如何我可以让 view 不被垃圾收集吗?

编辑:

程序中没有其他地方将 state 设置为 1 或任何其他值。 view 永远不会在程序中的任何位置设置为 null。你看到的是整个功能代码,我只删除了变量声明和初始化,没有一个涉及 stateviewstateview 都被声明为 private

这段代码是我在Unity中做的一个测试项目。

编辑:

这不是一个固定的问题,它只是偶尔发生一次,而且似乎涉及某种时间安排,因为直到现在我在调试器打开的情况下完全无法重复这个问题。

【问题讨论】:

  • state1 不足以证明 if 块中的代码已经运行。问题是在其他地方设置 state 或其他代码将 view 设置为 null。
  • @lc 其他地方?在哪里?外质密码?除了变量声明和通过 Awake 进行的一些初始化之外,这几乎是整个程序,没有其他地方状态变为 1,也没有 view=null,这就是我首先发布这个问题的原因。
  • 我 99% 确定这与垃圾回收无关,但你能发布Label 的代码吗?
  • @lc 我无法发布该代码,因为它是 Unity 的一部分,它是内部的,我无权访问它。
  • 如果view 是在OnGUI 方法之外定义的,那么它不会被垃圾回收。如果它是null,那么要么它从未被设置,要么它被其他东西设置为null。我怀疑它是“外质代码”。您确定没有其他代码修改任何这些变量?如果不是,那么为什么在类范围内而不是在 OnGUI 方法内声明它们?

标签: c# user-interface garbage-collection unity3d


【解决方案1】:

据我所知,mark 正在计算 HOW MANY 数组槽有多少值,而分配它们的索引是 I。所以,这是可能发生的一种情况:

空,空,空,1,空,0,2

其中标记为 3,行数为 7。第二个用于标记的计数,访问前三个空元素。

我知道您将数组中的每个条目都设置为 new Log(),但这是一个非常有效的逻辑错误。另外,可能为 null 的对象不是 view OR view[I],而是 view[I].time?逐行跟踪代码,我们就知道了。

【讨论】:

  • 问题不是:view[i]==null,问题是:view==null,就好像第70行没有执行,但是如果第70行没有执行,那@987654323怎么解释@和state==1???如果new 失败,你如何解释第 72 行没有抛出异常?我能找到的唯一合乎逻辑的解释是垃圾收集问题。
  • 如果你仔细阅读你会意识到这个问题,正如我所测试的那样,当有一个活动断点时不会发生,所以直到今天我一直无法跟踪程序,我发布这个问题的原因。
  • 我有 MonoDevelop 设置来打破异常,当异常发生时我检查了所有变量并且所有变量都有正确的值,除了 viewnull,即: view==null.
  • 我没有看到您的代码在任何地方检查 state == 1。至于马克,我不知道。你可以在这里发布整个代码吗?你的这个例外让我非常好奇!
【解决方案2】:

我仍然不知道为什么会出现这个问题,而且可能永远不会。我修改了 OnGUI,所以 ifview==null 而不是 控制state==0,这样如果由于某种奇怪的原因 view 变为 null 它会被恢复。 p>

【讨论】:

  • 我建议您继续调试以找到问题的根本原因。不理解自己的代码是灾难的根源。
猜你喜欢
  • 2010-11-10
  • 2014-07-24
  • 2014-05-03
  • 1970-01-01
  • 2012-04-21
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
相关资源
最近更新 更多