当前位置:网站首页>Three singleton modes of unity (hungry man, lazy man, monobehavior)
Three singleton modes of unity (hungry man, lazy man, monobehavior)
2022-07-07 15:55:00 【Listen to the rain outside the window】
Unity The next three singleton modes
Single example usage scenario
The object is globally unique , And often used .
static Introduction to static fields
- All objects share static attribute , namely static Attributes are unique in this class .
- static Properties will not be GC Recycling , Create as the program begins , Destroy as the program ends (so Don't abuse single cases )
I've learned object-oriented buddy pairs static It must be no stranger , Its characteristics are very similar to the single case to be explained today , Naturally, the subsequent singleton mode will also be used .
warren :static Why are attributes uniquely shared in a class ?
C# All classes created in will have a globally unique type object (System.Type), The function table of this class will be saved in the type object , Static fields, etc , In other words, static fields are stored in globally unique type objects , Rather than exist in such new Out of the instance object , Now we can well explain the two properties of static fields .
Ordinary C# class — Hungry Chinese style
For better code reuse , The following three singleton patterns will adopt the design method of tool classes , That is, it is designed as a generic parent class , Subclasses that want to implement the singleton pattern only need to inherit the corresponding singleton tool class !
namespace Common
{
/// <summary>
/// Hungry Chinese singleton mode generic parent
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> where T : Singleton<T> // Add generic constraint as T Must be itself or a subclass
{
// Prevent objects from being created outside , Destroy uniqueness
protected Singleton() {
}
public static T Instance {
get; private set; }
// Static constructor , Called when the program starts
static Singleton()
{
Instance = Activator.CreateInstance(typeof(T), true) as T;
Instance.Init(); // Initialize once
}
/// <summary>
/// Optional initialization function
/// </summary>
protected virtual void Init()
{
}
}
}
- Provide virtual functions Init, You can rewrite this Init Initialize the class , There is no need to use a constructor to prevent multiple calls .
- Using generic delay to declare singleton schema objects , Subclasses can easily implement the singleton pattern by inheriting this parent class and assigning their own types to singletons ,where For generics T Constraints must be themselves or subclasses .
- A single example of starving Chinese style , That is, at the beginning of the program, the singleton static attribute Instance To initialize , Two characteristics of hungry Han style
- Starving singletons are thread safe ,static The constructor can only run once
- Hungry Han style singleton has the risk of null reference , If in another class static This singleton is referenced in the constructor , Because of the running order, this singleton may not be instantiated yet , An empty reference error will be reported . This is in MonoBehavior It is particularly obvious in the single example of script !
Use a chestnut
using Common; // Note the reference to the namespace
public class Test : Singleton<Test>
{
private string str;
protected override void Init()
{
base.Init();
str = "Hello World";
}
public string SayHello()
{
return str;
}
}
public class TestMono : MonoBehaviour
{
private void Awake()
{
string str = Test.Instance.SayHello();
Debug.Log(str);
}
}
Ordinary C# class — Slacker type
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common
{
/// <summary>
/// Singleton class lazy loading
/// </summary>
public class SingletonLazy<T> where T:SingletonLazy<T>
{
private volatile static T instance;
/*volatile modification : The compiler will fine tune the order of the code when compiling the code , use volatile Modification ensures the order of strict meaning . One definition is volatile The variable is that it can be changed unexpectedly , such , The compiler will not assume the value of this variable . To be precise, it means , The optimizer must carefully reread the value of this variable every time it is used , Instead of using a backup stored in a register .*/
private static object locker = new object();
public static T Instance {
get
{
// Double check Avoid multiple access thread lock and multi-threaded access conflict
if(instance == null)
{
lock(locker)
{
if(instance==null)
{
instance = Activator.CreateInstance(typeof(T), true) as T;
instance.Init(); // Guaranteed to be called only once
}
}
}
return instance;
} }
/// <summary>
/// Optional initialization function
/// </summary>
public virtual void Init()
{
}
}
}
- An example of lazy style , Load on demand , Load the first time you use this object , There are also some characteristics of lazy singleton
- Lazy singletons are non thread safe , There may be multiple calls at the same time , It will violate the globally unique feature of a singleton .
- Multi thread conflict problem , Naturally, I think of using locks to isolate , Ensure that only one thread can be instantiated at the same time , In order to make the first thread instantiate , Subsequent threads that are locked and isolated will not be instantiated repeatedly when entering, and the internal part of the lock needs to be re checked and empty .
- Due to the performance consumption of the lock , After the first instantiation , Subsequent call requests do not need to be blocked by locks before being judged null , A second check can be added outside the lock .
- volatile In order to prevent address problems with minimal probability , In most cases, it can be ignored , If you want to pursue extreme rigor, you also need to add this attribute , The reason has been explained in the notes .
- Lazy singletons are non thread safe , There may be multiple calls at the same time , It will violate the globally unique feature of a singleton .
Script class — The hungry + lazy
namespace Common
{
///<summary>
/// Script singleton class , Responsible for creating instances for unique scripts
///<summary>
public class MonoSingleton<T> : MonoBehaviour where T:MonoSingleton<T> // Note that this constraint is T Must be itself or a subclass
{
private static T instance; // Create private object record value , You can assign values only once to avoid multiple assignments
public static T Instance
{
// Implement on-demand loading
get
{
// When it has been assigned , You can go back directly
if (instance != null) return instance;
instance = FindObjectOfType<T>();
// To prevent the script from hanging on the object , Exception not found , You can create an empty object and hang it
if (instance == null)
{
// If you create an object , The script on it will be called when it is created Awake That is to call T Of Awake(T Of Awake Is actually the name of the inherited parent class )
// So there is no need to instance assignment , It will be in Awake Assignment in , It will initialize naturally, so there is no need to init()
new GameObject("Singleton of "+typeof(T)).AddComponent<T>();
}
else instance.Init(); // Guarantee Init Only once
return instance;
}
}
private void Awake()
{
// If there are no other scripts Awake Call this instance , Then you can Awake Self initialization in instance
instance = this as T;
// initialization
Init();
}
// Subclasses initialize members if placed in Awake There will still be Null So make one by yourself init Function solution ( It's not necessary to use it )
protected virtual void Init()
{
}
}
}
- Mono The singleton of the script is compared with ordinary C# Some change points of single case
- Mono The instantiation method of script cannot rely on new, Instead, mount to GameObject On the body , If it is pre mounted in the scene, you can get it directly , If it is not mounted, it is automatically created GameObject And mount it .
- Provide on-demand loading and initial loading , On demand loading is still get In the middle of , The initial load cannot be executed in the constructor , But in the script life cycle Awake Function .
- Some people may wonder where objects are automatically created instance The problem of assignment , Actually create GameObject After AddComponent I'll do it once Awake If you assign another value Instance or Init It violates the characteristics of singleton .
- Use this sophisticated Mono Singleton parent , At the same time, realize the hungry and lazy , There is no need to worry about Awake Null pointer exception caused by calling sequence , Just use it boldly !
ending
Singleton mode is a commonly used tool class , With these three scripts, you can encounter single case requirements in development , Direct inheritance is enough , Tool classes can greatly improve the speed of development , And there is no need to do a lot of repetitive work , Later, the author will gradually share the tool classes used in his development process !
边栏推荐
- LeetCode2_ Add two numbers
- 讲师征集令 | Apache SeaTunnel(Incubating) Meetup 分享嘉宾火热招募中!
- Use of SVN
- Matlab experience summary
- Please supervise the 2022 plan
- numpy--数据清洗
- 融云斩获 2022 中国信创数字化办公门户卓越产品奖!
- Actually changed from 408 to self proposition! 211 North China Electric Power University (Beijing)
- Learn good-looking custom scroll bars in 1 minute
- Getting started with webgl (1)
猜你喜欢
Actually changed from 408 to self proposition! 211 North China Electric Power University (Beijing)
numpy---基础学习笔记
AE learning 02: timeline
航运船公司人工智能AI产品成熟化标准化规模应用,全球港航人工智能/集装箱人工智能领军者CIMC中集飞瞳,打造国际航运智能化标杆
Getting started with webgl (4)
20th anniversary of agile: a failed uprising
【微信小程序】Chapter(5):微信小程序基础API接口
[wechat applet] Chapter (5): basic API interface of wechat applet
【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
Monthly observation of internet medical field in May 2022
随机推荐
Steps to create P8 certificate and warehousing account
LeetCode3_ Longest substring without duplicate characters
[Lanzhou University] information sharing of postgraduate entrance examination and re examination
Clang compile link ffmpeg FAQ
Cocos makes Scrollview to realize the effect of zooming in the middle and zooming out on both sides
leetcode 241. Different ways to add parentheses design priority for operational expressions (medium)
Super signature principle (fully automated super signature) [Yun Xiaoduo]
Cocos uses custom material to display problems
有钱人买房就是不一样
A wave of open source notebooks is coming
Cocos creator collision and collision callback do not take effect
Streaming end, server end, player end
[markdown grammar advanced] make your blog more exciting (IV: set font style and color comparison table)
Vite path alias @ configuration
[original] all management without assessment is nonsense!
The significance of XOR in embedded C language
Getting started with webgl (2)
Iterator and for of.. loop
Tkinter after how to refresh data and cancel refreshing
When opening the system window under UE4 shipping, the problem of crash is attached with the plug-in download address