首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有罕见空引用的统一代码,我无法找出

带有罕见空引用的统一代码,我无法找出
EN

Stack Overflow用户
提问于 2022-04-08 09:34:52
回答 2查看 607关注 0票数 2

我有一个简单的功能,在我的统一游戏代码,我正在寻找一个“工作地点”-一个空的地方为我的NPC做一些工作。

这段代码在99.999%的时间里运行得很好,但是偶尔会抛出一个空引用异常,我无法在我的一生中弄清楚它的位置。我试着抓住所有可能的地方,那里有东西可能没有分配,但却找不到。在某些奇怪的情况下,我的代码中一定有某种边缘情况,或者代码中的某些东西行为不正常。

所以我的代码是有缺陷的,我不知道在哪里。帮我改进一下:

代码语言:javascript
复制
    public Transform[] workSpots;


    public Transform findAvailableWorkSpot() {
        if (workSpots == null || workSpots.Length == 0) return null; // sometimes we have no work spots
        int i=0;
        while (i<10) {
            Transform spot = workSpots[Random.Range(0, workSpots.Length)];
            if (spot != null && spot.childCount == 0) {
                return spot;
            }
            i++;
        }
        // couldn't find one randomly, let's just iterate over them:
        foreach (Transform spot in workSpots) {
            if (spot != null && spot.childCount == 0) {
                return spot;
            }
        }

        Debug.LogError("could not find free workspot on "+gameObject.name);
        return null;
    }

逻辑:

  • 首先,尝试最多10次获得一个免费的随机工作点。当他在那里工作的时候,我把NPC放在工作点上,所以如果这个点现在没有NPC,那么spot.childCount == 0是真的。
  • ,如果失败了,那么我只需要遍历所有的,并选择第一个空闲的。在这里返回空是可以的,调用代码将处理

诊断后端告诉我,每天有2-4次的人在这个函数中经历一个空引用异常,但是诊断并不告诉我行号,而且我从未在本地看到过它。我一遍又一遍地看着它,我找不到它可能在哪里。也许我的代码有更基本的问题吗?

其他信息:

  • 工作点是在works ()中初始化的,从此不再更改,因此我确信函数开始时的测试工作正常,并且在函数运行时不可能变为null。
EN

回答 2

Stack Overflow用户

发布于 2022-04-08 10:01:40

这并不是对异常的确切来源的直接回答。

但是,如果您开放使用Linq,您可以简化您的代码很多!

我只想用

代码语言:javascript
复制
using System.Linq;

...

public Transform[] workSpots;

public bool TryFindAvailableWorkSpot(out Transform freeSpot)
{
    // First heck this component even is alive
    if (!this || workSpots == null || workSpots.Length == 0)
    {
        freeSpot = null;
        return false;
    }

    // First "Where" filters out only those spots that exist and have no children
    // then "OrderBy" randomizes these results
    // then we take the first one or null if there isn't any
    freeSpot = workSpots.Where(spot => spot && spot.childCount == 0).OrderBy(spot => Random.value).FirstOrDefault();

    // use the implicit bool operator for checking if we have found a valid reference
    return freeSpot;
}

然后代替使用

代码语言:javascript
复制
var spot = yourClass.findAvailableWorkSpot();

并且必须再次检查null和潜在的异常,您最好在同一行中使用以下方法进行检查。

代码语言:javascript
复制
if(yourClass.TryFindAvailableWorkSpot(out var spot))
{
    ... Do someting with spot
}
else
{
    Debug.LogError("could not find free workspot");
}

看见

票数 1
EN

Stack Overflow用户

发布于 2022-04-08 09:53:11

我认为你找的地方不对,例外的地方发生了。按照您编写代码的方式,不可能使workSpots为空或空。

我唯一能看到空引用异常发生的地方是,如果您试图访问workSpots[index] ->,并且返回一个空的转换对象并尝试使用它(但是在您的代码中您已经为此做好了准备)。在尝试访问转换之前,使用该方法的位置可能不检查要返回的转换是否为空。如果您的代码编写得很好,而且您不相信,那么在尝试记录错误时,空引用异常可能是由gameObject.name引起的。如果不是那样的话,我真的不知道。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71794741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档