问题描述
我想知道哪种方法是使用单例实例的正确方法:当我创建一个名为"Manager"的单例类,并且它包含一个名为"value"的int变量,而我又有一个名为"A"的类.../p>
:public class YourManagerMono : MonoBehaviour { } public sealed class Manager { private static readonly Manager instance = new Manager(); //use a gameobject to relate it in the scene private YourManagerMono monoManager; public static Manager Instance => instance; // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Manager() {} private Manager() { //find or create a manager monoManager = GameObject.FindWithTag("Manager").GetComponent<YourManagerMono>(); if (monoManager == null) { monoManager = new GameObject().AddComponent<YourManagerMono>(); monoManager.gameObject.tag = "Manager"; Object.DontDestroyOnLoad(monoManager.gameObject); } } }Jon Skeet撰写的有关C#的单例实现的很棒的文章(我使用实现4)./p>
我再次同意derHugo(在有关此答案的新评论中).我的示例用于显示有趣的预期结果并提供尽可能多的性能,但是如果您只需要具有第1点和第3点的Monohhaviour,则可以继续使用单身人士的通用实现(请记住将结束类设置为密封形式,以帮助编译器).I am wondering which is the right way to use singleton instance: when I create a singleton Class called "Manager" and it contains an int variable called "value" and I have a another class called "A"...
//singleton class using System.Collections; using System.Collections.Generic; using UnityEngine; public class Manager : MonoBehaviour { public static Manager Instance{ set; get;} public int value; private void Awake () { if (Instance == null) { Instance = this; DontDestroyOnLoad (this.gameObject); } else { Destroy (gameObject); } } }So inside my A class I can make a instance of the singleton like this: // example pseudo code public class A {
// First // using as a global variable Manager manager; //------------------------------------ Public void tstOne(){ // First // using that global variable manager.Instance.value = 0; // Second // or this way Manager.Instance.value = 0; } Public void tstTwo(){ // First // using that global variabl manager.Instance.value = 1; // Second // or this way Manager.Instance.value = 1; } }So my problem is - should I create A global instance and then use that instance like in first one or should I use the second example?
Are they both are same in terms of memory consumption and efficiency?Or is there another way to use singletons?
解决方案I confirm Ruzihm answer (and I also agree with derHugo comment, I personally prefer SO and reference them where required. Much cleaner than Singleton or DI direct approach).
To be specific accessing the instance member manager.Instance.value is slower and also requires further memory allocation on the heap so it hurts both memory usage and speed performance. (Very small performance issues, but still.)
There's also further room of improvement on the singleton, especially if you do not require it to derive from MonoBehaviour.
You can:
- Make sure it is build also if you forget to add it in the scene
- Make it thread safe (not required by unity, usually)
- Implement it lazily (means you create it only when you need it)
- Also, as a general rule is better to seal the singleton class for improved performance (again really slight improvement when you use virtual methods)
This would be the implementation (considering you use the Manager as helper instance and YourManagerMono if you require monobehaviour logic:
public class YourManagerMono : MonoBehaviour { } public sealed class Manager { private static readonly Manager instance = new Manager(); //use a gameobject to relate it in the scene private YourManagerMono monoManager; public static Manager Instance => instance; // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static Manager() {} private Manager() { //find or create a manager monoManager = GameObject.FindWithTag("Manager").GetComponent<YourManagerMono>(); if (monoManager == null) { monoManager = new GameObject().AddComponent<YourManagerMono>(); monoManager.gameObject.tag = "Manager"; Object.DontDestroyOnLoad(monoManager.gameObject); } } }A great article about singleton implementation for C# by Jon Skeet (I used implementation 4).
EDIT:
Again I agree with derHugo (in the new comment on this answer). My example is used to show an interesting prospective and to offer as much performance as I can, but if you just require a Monobehaviour with just point 1 and 3 you may go ahead with a generic implementation of singleton from Unify Community (just remember to set the end class as sealed to help the compiler).这篇关于统一使用Singleton的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!