OnDestroy在Unity中可靠吗?
c#
在 Unity 中,我有一个脚本,我在其中通过 TCP 连接到套接字,并希望在每一帧都使用此连接。之后我需要处理和清理。我的想法是用来Start()开始连接和OnDestroy()
public class Foo : MonoBehaviour
{
void Start()
{
// start TCP connection
}
void Update()
{
// use connection
}
void OnDestroy()
{
// cleanup
}
}
我需要清理来执行任何发生的事情。OnDestroy()无论对象发生什么情况,该方法是否保证在应用程序停止之前(在独立模式和编辑器中)被调用?如果没有,我如何保证清理?
回答
不它不是!
OnApplicationQuit当您的应用程序因某种原因崩溃时,甚至可能不会被调用。
还有其他特定情况,两者都没有被调用。我知道,根据我自己的经验,例如在 HoloLens2 上的应用程序并未关闭,而只是处于休眠状态。如果您然后通过 HoloLens 主“菜单”关闭它们,那么您实际上是通过任务管理器杀死它们。
这是非常脏,原因既不OnDestroy也不OnApplicationQuit或任何其他特定的统一消息被调用,我们结束了佐比线程和依然占据TCP端口。
如果你真的想确定(例如为了免费连接,杀死线程等)我最终做的是用解构器(Finalizer)创建一个专用类
解构器是纯 c# 并且不依赖于 Unity 的正确关闭,因此即使垃圾收集器自动完成其工作后应用程序因崩溃而终止,也能保证调用它。
public class Foo : MonoBehaviour
{
private class FooInternal
{
public FooInternal()
{
// create TCP connection
// start thread etc
}
public void Update ()
{
// e.g. forward the Update call in order to handle received messages
// in the Unity main thread
}
public ~FooInternal()
{
// terminate thread, connection etc
}
}
private FooInternal _internal;
void Start()
{
_internal = new FooInternal ();
}
void Update()
{
_internal.Update();
}
}
如果你从不传递对_internal其他任何东西的引用,GC 也应该在这个实例被销毁后自动终止它。