Unity 프레임워크 학습--3

싱글톤 패턴 기본 클래스

객체의 외부 생성을 방지하기 위한 생성자 사유화

외부 접근을 위한 속성을 제공하세요. 이 속성은 이 클래스의 유일한 객체와 동일합니다.

게으른 남자 모드와 배고픈 남자 모드로 구분됩니다.

MonoBehaviour를 상속하지 않는 싱글톤 모드

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

MonoBehaviour의 싱글톤 모드 상속

public class MyUiManager : MonoBehaviour
{
    private MyUiManager() { }

    private static MyUiManager instance;

    public static MyUiManager Instance 
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<MyUiManager>();
            }
            return instance;
        }
    }
}

 인스턴스 = FindObjectOfType<MyUiManager>();

 MonoBehaviour를 상속받은 싱글톤은 게임 씬에 걸리게 되는데, 게임 씬에서 찾아 할당해야 합니다.

상속과 비상속은 초기화 방법이 다릅니다.

MonoBehaviour의 자동 싱글톤 모드 상속

if (instance == null)
            {
                instance = FindObjectOfType<MyUIManager>();
                //游戏场景中没有创建物体挂在脚本,写代码来自动做这些事情
                if (instance == null)
                {
                    GameObject go = new GameObject("MyUIManager");  //创建游戏对象
                    instance = go.AddComponent<MyUIManager>();  //挂载脚本到游戏对象身上
                }
            }

 MonoBehaviour를 상속받은 싱글톤 모드에서 장면 전환 문제

if (instance == null)
                {
                    GameObject go = new GameObject("MyUIManager");  //创建游戏对象
                    instance = go.AddComponent<MyUIManager>();  //挂载脚本到游戏对象身上
                }
                DontDestroyOnLoad(instance);   //让游戏对象切换场景时不销毁

MonoBehaviour를 상속하지 않는 싱글톤 모드 기본 클래스

/// <summary>
/// 不继承MonoBehaviour 的单例模式基类
/// 作用:继承了这个这个类的类自带单例模式
/// </summary>
public class SingletonPatternBase<T> where T: SingletonPatternBase<T>
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                //where 里面要求含有无参构造函数  where T :new()
                //....单例怎么能有无参构造函数呢
                //instance = new T();
                
                //或者利用反射调用无参构造方法来构造
                instance = Activator.CreateInstance(typeof(T), true) as T;
            }
            return instance;
        }
    }

    //构造方法私有化  private 的话子类也无法继承对象,所以使用protected
    protected SingletonPatternBase() { }

}

MonoBehaviour를 상속하는 싱글톤 모드 기본 클래스

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonMonoAutoBase<T> : MonoBehaviour where T:MonoBehaviour
{
    protected SingletonMonoAutoBase() { }

    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<T>();
                if (instance == null)
                {
                    GameObject go = new GameObject(typeof(T).Name);  //创建游戏对象
                    instance = go.AddComponent<T>();  //挂载脚本到游戏对象身上
                }
            }
            return instance;
        }
    }
}

MonoBehaviour를 상속하는 싱글톤 모드 기본 클래스의 장면 전환 문제

OnDestroy 메서드에서 싱글톤 개체에 액세스하는 중에 문제가 발생했습니다.

OnDestroy 메서드가 실행되면 리소스가 지워지고 인스턴스 감지가 비어 있으며 새 개체가 자동으로 생성되므로 오류가 보고됩니다.

해결책:

    //싱글톤 객체 존재 여부를 기록하며, OnDestory 메소드에서 싱글톤 객체에 접근할 때 오류를 방지하기 위해 사용됩니다.
    public static bool isExisted { get; private set; } = false;

보호된 가상 무효 OnDestroy()
    {   
        isExisted = false; 
    } 

 다중 스레드가 싱글톤에 액세스할 때 발생하는 문제

 운영 체제 스레드 잠금 문제

//线程锁。当多线程访问时,同一时刻只允许一个线程访问
    private static object locker = new object();

    //volatile关键字修饰的字段,当多个线程都对它进行修改时,可以确保这个字段在任何时刻呈现的都是最新的值
    private volatile static T instance;

    public  static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock(locker)
                {
                    if (instance == null)
                    {
                        //或者利用反射调用无参构造方法来构造
                        instance = Activator.CreateInstance(typeof(T), true) as T;
                    }
                }
            }
            
            return instance;
        }
    }

추천

출처blog.csdn.net/zaizai1007/article/details/132279554