我有一个简单的功能,在我的统一游戏代码,我正在寻找一个“工作地点”-一个空的地方为我的NPC做一些工作。
这段代码在99.999%的时间里运行得很好,但是偶尔会抛出一个空引用异常,我无法在我的一生中弄清楚它的位置。我试着抓住所有可能的地方,那里有东西可能没有分配,但却找不到。在某些奇怪的情况下,我的代码中一定有某种边缘情况,或者代码中的某些东西行为不正常。
所以我的代码是有缺陷的,我不知道在哪里。帮我改进一下:
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;
}逻辑:
spot.childCount == 0是真的。。
诊断后端告诉我,每天有2-4次的人在这个函数中经历一个空引用异常,但是诊断并不告诉我行号,而且我从未在本地看到过它。我一遍又一遍地看着它,我找不到它可能在哪里。也许我的代码有更基本的问题吗?
其他信息:
发布于 2022-04-08 10:01:40
这并不是对异常的确切来源的直接回答。
但是,如果您开放使用Linq,您可以简化您的代码很多!
我只想用
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;
}然后代替使用
var spot = yourClass.findAvailableWorkSpot();并且必须再次检查null和潜在的异常,您最好在同一行中使用以下方法进行检查。
if(yourClass.TryFindAvailableWorkSpot(out var spot))
{
... Do someting with spot
}
else
{
Debug.LogError("could not find free workspot");
}看见
发布于 2022-04-08 09:53:11
我认为你找的地方不对,例外的地方发生了。按照您编写代码的方式,不可能使workSpots为空或空。
我唯一能看到空引用异常发生的地方是,如果您试图访问workSpots[index] ->,并且返回一个空的转换对象并尝试使用它(但是在您的代码中您已经为此做好了准备)。在尝试访问转换之前,使用该方法的位置可能不检查要返回的转换是否为空。如果您的代码编写得很好,而且您不相信,那么在尝试记录错误时,空引用异常可能是由gameObject.name引起的。如果不是那样的话,我真的不知道。
https://stackoverflow.com/questions/71794741
复制相似问题