Unity中的单例总结

Unity中的单例总结

单例模式是程序员在编程时接触到的最基础设计模式之一,简单一句话概括就是对象的唯一实例。

在unity中的单例模板有以下几种

非Monobehavior下的单例

  • 使用反射的单例模式
using System;
using System.Reflection;

public abstract class Singleton where T : Singleton
{
  protected Singleton()
  {
    Init();
  }

  protected static T instance = null;

  public static T Instance
  {
    get
    {
      if (instance == null)
      {
        var constructors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
        var constructor = Array.Find(constructors, c => c.GetParameters().Length == 0);
        if (constructor == null)
          throw new Exception("non-public constructor not find");
        instance = constructor.Invoke(null) as T;
      }
      return instance;
    }
  }

  protected virtual void Init() { }
  
}

使用反射获取非公有 构造无参函数,并进行初始化

  • 使用关键字 new() 限定,必须含有无参构造函数的单例
using System;
using System.Reflection;

public abstract class Singleton where T : Singleton, new()
{
  protected Singleton()
  {
    Init();
  }

  protected static T instance = null;

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

  protected virtual void Init() { }
    
}

使用new()关键字限定无参构造函数,子类继承时必须实现公有构造函数

  • 使用双重锁的单例模式
using System;
using System.Reflection;

public abstract class Singleton where T : Singleton
{
  protected Singleton()
  {
    Init();
  }

  protected static T instance = null;

  private static readonly object objectLock = new object();

  public static T Instance
  {
    get
    {
      if (instance == null)
      {
        lock (objectLock)
          if (instance == null)
          {
            ...初始化过程...
          }
      }
      return instance;
    }
  }

  protected virtual void Init() { }
  
}

使用 双重锁确保单例在多线程初始化时的线程安全性

MonoBehavior的单例实现

using UnityEngine;

public class BehaviorSingleton : MonoBehaviour where T : BehaviorSingleton
{
  private static T instance = null;

  public static T Instance
  {
    get
    {
      if (instance == null)
      {
        instance = FindObjectOfType();
        if (instance == null)
        {
          var gameObject = new GameObject(typeof(T).Name);
          DontDestroyOnLoad(gameObject);
          instance = gameObject.AddComponent();
        }
      }
      return instance;
    }
  }

  private void Awake()
  {
    //确保唯一性
    if (instance == null)
    {
      DontDestroyOnLoad(gameObject);
      gameObject.name = typeof(T).Name;
      instance = GetComponent();
      InstanceAwake();
    }
    else
      Destroy(gameObject);
  }


  private void OnApplicationQuit()
  {
    instance.InstanceDestroy();
    instance = null;
  }

  protected virtual void InstanceAwake() { }
  protected virtual void InstanceDestroy() { }

}

你可能感兴趣的:(Unity中的单例总结)