文章目录
Hololens2初入——Unity正常运行,真机运行出问题汇总(持续更新)
PS 建议以后如果是自己写的类,那么在调用相关成员的时候,做好null的逐层检查。 另外,在继承 mono类的时候,把变量的初始化都放到awake里面。 不要在声明的同时赋值。
NullReferenceException: Object reference not set to an instance of an object
这类型的问题大都是因为声明的变量没有被实例引起的,但是我这边的这个情况不是这类型的原因。
- 原因: 在代码中单独声明了
dynamic
类型的变量。
public dynamic data;
别问我为什么这个会报错,只能问微软大佬们。正常在电脑unity中都是可以用的,但是发布到Hololens2里面就出错。
- 措施: 将这个变量设置为一个内部字典(列表没试过),字典的值是
dynamic
类型,然后另设一个public object
类型的变量来访问这个字典里面的值,具体代码如下面
private Dictionary<string, dynamic> data = new Dictionary<string, dynamic>();
public object Data
{
get
{
return data["data"];
}
set
{
data["data"] = value;
}
}
———— 以下是调试用的一些代码资料和结果截图,方便完善文章用的,以后有空解释下发现这个问题的过程,不完全正确,先别看————
下面字典接收的是一个dynamic
类型,
Dictionary<string, dynamic> msgSend_发送的消息 = new Dictionary<string, dynamic>() {
{
"test1", false}};
try
{
var n = 0;
msgSend_发送的消息.Add("test2", dicShareInfos_共享信息字典.Count);
foreach (var infos共享信息 in dicShareInfos_共享信息字典)
{
n += 1;
try
{
if (infos共享信息.Key != null && infos共享信息.Value != null)
{
msgSend_发送的消息.Add("test_" + n.ToString(), true);
try
{
if (infos共享信息.Value.Data is null)
{
msgSend_发送的消息.Add(infos共享信息.Key, 0);
}
else
{
msgSend_发送的消息.Add("infos1", 1);
dynamic c = true;
try
{
if (c is null)
{
msgSend_发送的消息.Add("errorCnum", 2);
}
else
{
msgSend_发送的消息.Add("errorCnum", 3);
}
}
catch (Exception e)
{
msgSend_发送的消息.Add("errorCC", e.Message);
}
try
{
msgSend_发送的消息.Add("type", c.GetType().ToString());
}
catch (Exception e)
{
msgSend_发送的消息.Add("type", "err");
}
try
{
msgSend_发送的消息.Add(c is null ? "infosK" : "infosF", 2);
msgSend_发送的消息.Add("infos2", c);
}
catch (Exception e)
{
msgSend_发送的消息.Add("error1", e.Message);
}
try
{
dynamic p = new Dictionary<string, bool>() {
{
"k", true}};
try
{
msgSend_发送的消息.Add("errorp1", p);
}
catch (Exception e)
{
msgSend_发送的消息.Add("errorp2", e.Message);
}
}
catch (Exception e)
{
msgSend_发送的消息.Add("errorp", e.Message);
}
try
{
bool k = (bool) c;
}
catch (Exception e)
{
msgSend_发送的消息.Add("kc", e.Message);
}
try
{
var b = infos共享信息.Value.Data;
msgSend_发送的消息.Add("infos4", 1);
}
catch (Exception e)
{
msgSend_发送的消息.Add("error4", e.Message);
}
try
{
msgSend_发送的消息.Add("infos5", infos共享信息.Value.Data);
}
catch (Exception e)
{
msgSend_发送的消息.Add("error5", e.Message);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
// msgSend_发送的消息.Add(infos共享信息.Value.Data.ToString(),1);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
catch (Exception e)
{
Debug.Log("访问了错误变量");
}
正常的图
报错的图
这是一个令人崩溃的BUG,十分底层。
这边的问题主要原因是由于将一个dynamic
修饰的变量 添加到一个Dictionary<string, dynamic>
字典中。在电脑untiy中测试的时候是没有任何问题的,但是发布到HL中的时候就会报这个错误。 这个问题是我通过一步一步发布到真机中并把错误发送到电脑中发现的。
由于 dynamic 的修饰,编译器将会自动把被修饰的变量编译成 一个object
类型的对象,也就是该变量被默认为object类型引用。由于它实际上指向的对象并不是一个object类型,可能是bool,列表,或者其他的,而这些对象并不是 object的实例。在电脑端运行,估计是在运行过程中会自动推断引用对象的类型,所以就不会出现这种错误,但是编译到Hololens2的时候,由于不能自行推断出对象类型,所以就会引发这个错误。
又是一段被真机毙掉的代码
TcpClient.msg_debug += "4";
var alu = value[info_某信息.Key];
TcpClient.msg_debug += "4-1:";
var value_值 = new Dictionary<string, dynamic>() {
{
"data", alu}};
TcpClient.msg_debug += "4-2:";
编译的时候记得把这个选上