在项目中,我们往往会使用到单例,当想清理一下单例了,该怎么做呢?本篇文章提供一个单例管理思路。
将项目中的单例分为两大类,一类是可以被清理的,一类是不可以被清理。定义两个单例的基类,项目中用到的单例,根据需求从这两个基类中选择性的派生。再另外定义一个类,类中定义两个字典,分别存放两种单例的所有实例,当需要实例的时候,分别从对应的字典中去取。对于可被清理的单例,通过 event 链去清理,这样看着要比遍历容器去清理要清爽的多。下面直接上代码。
不可被清理的单例基类:
1 public class ManagerSingleton<T> where T : class, new() 2 { 3 private static T _instance; 4 5 public static T Instance 6 { 7 get 8 { 9 if (null == _instance) 10 { 11 _instance = ApplicationManager.GetSingleton(typeof(T).FullName) as T; 12 } 13 return _instance; 14 } 15 } 16 }
可被清理的单例基类:
1 public class ReleaseSingleton<T> where T : class, new() 2 { 3 private static T _instance; 4 5 public static T Instance 6 { 7 get 8 { 9 if (null == _instance) 10 { 11 _instance = ApplicationManager.GetReleaseSingleton(typeof(T).FullName) as T; 12 ApplicationManager.eventReleaseSingleton -= Release; 13 ApplicationManager.eventReleaseSingleton += Release; 14 } 15 return _instance; 16 } 17 } 18 19 static void Release() 20 { 21 _instance = null; 22 } 23 }
单例管理类:
1 using System; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class ApplicationManager 6 { 7 static private Dictionary<string, object> dictSingleton = new Dictionary<string, object>(); //存放所有 不可被 清理的单例 8 static private Dictionary<string, object> dictSingletonRelease = new Dictionary<string, object>(); //存放所有 可以被 清理的单例 9 10 #region 不可被清理单例 11 public static object GetSingleton(string singletonType) 12 { 13 object singleton; 14 15 if (!dictSingleton.TryGetValue(singletonType, out singleton)) 16 { 17 singleton = Activator.CreateInstance(Type.GetType(singletonType)); 18 dictSingleton.Add(singletonType, singleton); 19 } 20 21 return singleton; 22 } 23 24 public static void RemoveSingleton(string singletonType) 25 { 26 if (dictSingleton.ContainsKey(singletonType)) 27 { 28 dictSingleton.Remove(singletonType); 29 } 30 } 31 #endregion 32 33 #region 可以被清理单例 34 public static object GetReleaseSingleton(string singletonType) 35 { 36 Debug.Log(singletonType); 37 object singleton; 38 if (!dictSingletonRelease.TryGetValue(singletonType, out singleton)) 39 { 40 singleton = Activator.CreateInstance(Type.GetType(singletonType)); 41 dictSingletonRelease.Add(singletonType, singleton); 42 } 43 44 return singleton; 45 } 46 47 public static void RemoveReleaseSingleton(string singletonType) 48 { 49 if (dictSingletonRelease.ContainsKey(singletonType)) 50 { 51 dictSingletonRelease.Remove(singletonType); 52 } 53 } 54 #endregion 55 56 #region 单例清理 57 58 public delegate void DeleReleaseSingleton(); 59 public static event DeleReleaseSingleton eventReleaseSingleton; 60 61 public static void ReleaseAllSingleton() 62 { 63 if (null != eventReleaseSingleton) 64 { 65 eventReleaseSingleton(); 66 eventReleaseSingleton = null; 67 } 68 dictSingletonRelease.Clear(); 69 70 GC.Collect(); 71 GC.WaitForPendingFinalizers(); //挂起当前线程,直到处理终结器队列的线程清空该队列为止。 72 } 73 74 #endregion 75 }
当需要清理的时候,调用管理类中的方法即可。