一 前言
为人所知的是,静态成员的生命周期作用域似乎与应用进程同寿(其实是与应用程序域同寿),而大家在UE(UnityEngine)里面玩耍时免不得与代码磕磕碰碰导致其重新编译,这肯定会导致所编译代码块的静态成员的生命周期结束,那么编译完后进入播放模式,回到编辑器模式,这个过程会不会导致静态成员的生命周期结束呢?本文今日便要来见见这个面目。
二 实验准备
1.一个新鲜出炉的空场景A
2.材料:一个测试用的单例TestSingleton, 一个静态类StaticClass,一个测试的mono类TestA。将此脚本随意拖到空场景A里面的某个东西里面。
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestA : MonoBehaviour
{
public void Awake()
{
Show();
StaticClass.StaticInt++;
TestSingleton.TestInt++;
TestSingleton.Singleton.Count = 666;
TestSingleton.Singleton.Name = "赵文昌";
}
//使用Odin插件的Button特性,这样就可以在编辑器下通过反射调用这个函数以观察单例了
[Button]
public void Show()
{
if (Application.isPlaying)
{
Debug.Log("播放模式");
}
else
{
Debug.Log("编辑模式");
}
Debug.Log("TestInt:" + TestSingleton.TestInt);
Debug.Log("Instance.Count:" + TestSingleton.Singleton.Count);
Debug.Log("Instance.Name:" + TestSingleton.Singleton.Name);
Debug.Log("StaticInt" + StaticClass.StaticInt);
}
}
public class TestSingleton
{
public static TestSingleton Singleton { get { if (_singleton == null) _singleton = new TestSingleton(); return _singleton; } }
static TestSingleton _singleton;
public static int TestInt = 0;
public int Count = 0;
public string Name = "叶万山";
TestSingleton()
{
Debug.Log("单例内存分配");
}
~TestSingleton()
{
Debug.Log("单例内存回收");
}
}
public static class StaticClass
{
public static int StaticInt = 0;
}
三 实验步骤
步骤1.随意搞点什么导致Unity重新编译后进入场景A,确保其控制台为空并且静态变量没分配内存

步骤2.播放,得到现象如下

步骤3.退出播放,进入编辑器模式,点击TestA组件Inspector面板上的Show按钮得到现象

步骤4.再次进入播放模式,得到现象4

四 实验现象讨论
现象2 是编译后首次进入播放模式,此时静态变量的内存分配从无到有,从TestA脚本的执行顺序上,在通过Show函数观察静态成员的值后,就把这些变量的值进行了修改。
现象3 从播放模式退出到编辑模式,通过TestA的Show函数观察静态变量的值,其Debug的内容与现象2是不同的,所以我们得知步骤2修改的值并未被重置,而且也没出现单例的在销毁时会出现的“单例内存回收”这样的内容,故其单例并未销毁。这里我们可以得出结论,从播放模式退出回到编辑模式下时,静态成员的内存并不会进行回收。
现象4 此现象是从编辑器模式到播放模式,观察Debug的顺序,竟是“单例内存回收”这样的字样最先出栈,然后是Show函数的执行,与现象2别无二致,故而我们窥得见从编辑器模式到播放模式时,脚本中的静态成员会重新分配内存。
五 实验结论
1.从编辑模式进入播放模式时,脚本中的静态成员的内存会重新分配。
2.从播放模式进入编辑模式时,脚本中的静态成员的内存不会重新分配。
六 延申讨论
为什么从编辑器模式进入播放模式时会导致静态成员内存重新分配?好困阿以后再说
1307

被折叠的 条评论
为什么被折叠?



