Unity3D-单例模式各种写法应用

单例模式就是保证类的实例的唯一性

一般来说所有的管理类都需要设置为单例模式,音频管理模块,UI管理模块,对象池等
单例模式有各种各样的写法,有很普通的单例模式,有很复杂的单例模式。有的单例模式需要考虑多线程共享的问题,就要进行加锁防止混乱。

一. 普通 非继承Mono单例

最常见,最普通的单例模式基类的写法,使用了泛型进行封装使用。通过static变量和static静态方法,达到程序运行过程中的类实例的唯一性。

public class BaseManager<T> where T : new()
{
    private static T instance;
	
	//非必须存在私有构造器,其主要目的是防止 使用new浪费内存
    private BaseManager()
    {
    }

    public static T GetInstance()
    {
        if (instance == null)
            instance = new T();
        return instance;
    }
}

二. 继承MonoBehaviour的脚本的单例模式基类

此种方法存在一个操作上的注意事项,要保证此脚本只挂载在场景中的唯一物体上。否则就会发生浪费内存的情况,因为 instance只能返回最后一个加载脚本的物体的实例。

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
   private static T instance;

   public static T GetInstance()
   {
      return instance;
   }

   protected virtual void Awake()
   {
      instance = this as T;
   }
}

三. 继承MonoBehaviour的Auto单例模式基类

此种写法解决了需要保证脚本在场景中挂在的唯一性问题。

/// 
/// 继承了种种自动创建的单例模式基类,不需要我们手动托或者api去加,如果需要使用直接GetInstance就行了
/// 
/// 
public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T GetInstance()
    {    
        //不需要手动拖拽脚本并且 无需检查脚本在场景中的唯一性
        if (instance == null)
        {
            GameObject obj = new GameObject();
            //设置对象的名称为脚本的名字
            obj.name = typeof(T).ToString();
            
            // 保证切换场景的时候,挂有此脚本的gameobject不被移除。
            // 单例模式需要保证程序运行全程都有唯一的实例在运行,存在于整个生命周期之中
            instance = obj.AddComponent<T>();
        }
        
        return instance;
    }
}

你可能感兴趣的:(Unity,unity,c#)