当前位置:网站首页>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 !
边栏推荐
- webgl_ Enter the three-dimensional world (2)
- Keil5 does not support online simulation of STM32 F0 series
- C4D learning notes 3- animation - animation rendering process case
- Streaming end, server end, player end
- Simple understanding and application of TS generics
- LeetCode3_ Longest substring without duplicate characters
- Three. JS introductory learning notes 0: illustration of how webgl and threejs work
- Mysql database backup script
- 15. Using the text editing tool VIM
- How to build your own super signature system (yunxiaoduo)?
猜你喜欢

【数字IC验证快速入门】18、SystemVerilog学习之基本语法5(并发线程...内含实践练习)

JS array foreach source code parsing

Asynchronous application of generator function

postman生成时间戳,未来时间戳

Three. JS introductory learning notes 07: external model import -c4d to JSON file for web pages -fbx import

Three. JS introductory learning notes 19: how to import FBX static model

The download button and debug button in keil are grayed out

Three. JS introductory learning notes 03: perspective projection camera

Three. JS introductory learning notes 10:three JS grid

星瑞格数据库入围“2021年度福建省信息技术应用创新典型解决方案”
随机推荐
【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
postman生成时间戳,未来时间戳
VS2005 strange breakpoint is invalid or member variable value cannot be viewed
Three. JS introductory learning notes 08:orbitcontrols JS plug-in - mouse control model rotation, zoom in, zoom out, translation, etc
XMIND frame drawing tool
深度之眼(六)——矩阵的逆(附:logistic模型一些想法)
Shader Language
Streaming end, server end, player end
How to deploy the super signature distribution platform system?
Mesh merging under ue4/ue5 runtime
numpy---基础学习笔记
【数字IC验证快速入门】20、SystemVerilog学习之基本语法7(覆盖率驱动...内含实践练习)
Apache Doris刚“毕业”:为什么应关注这种SQL数据仓库?
Nacos conformance protocol cp/ap/jraft/distro protocol
OpenGL's distinction and understanding of VAO, VBO and EBO
Actually changed from 408 to self proposition! 211 North China Electric Power University (Beijing)
Use moviepy Editor clips videos and intercepts video clips in batches
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
[quick start of Digital IC Verification] 23. AHB sramc of SystemVerilog project practice (3) (basic points of AHB protocol)
[quick start of Digital IC Verification] 18. Basic grammar of SystemVerilog learning 5 (concurrent threads... Including practical exercises)