diff --git a/HowToUseWeaklyScripts.md b/HowToUseWeaklyScripts.md index 0924234..d26fedf 100644 --- a/HowToUseWeaklyScripts.md +++ b/HowToUseWeaklyScripts.md @@ -33,36 +33,52 @@ ### 隐式提升为单例(隐式声名) -你可以直接在代码中通过超级单例访问实例,而不用在乎这个类是否实现过单例,通过超级单例获取的单例实例与这个类是无关的。 +你可以直接在代码中通过超级单例访问实例,而不用在乎这个类是否实现过单例。 + ``` csharp -// 直接通过实例访问,如果这个类还没有在世界场景中生成,那么这一步会立刻创建一个实例在世界中 -SingleMonoBase.Instance +// 超级单例只能作用在组件脚本上,比如随便声名一个脚本 +public class TestScript: MonoBehaviour +{ + // 一些其他与单例实现无关的逻辑 +} -// 可以使用带有全局标识的实例进行访问,区别是,这会创建在dontdestroy世界中 -SingleMonoBase.GlobalInstance +// 接下来直接通过超级单例访问: +TestScript inst = SingleMonoBase.Instance; +// 1. 如果这个类还没有在世界场景中生成,那么这一步会立刻创建一个实例在世界中。 +// 2. 如果这个类已经存在,但是还没有通过超级单例访问,那么超级单例会首先尝试在场景中查找,然后根据你调用的作用域将他转移到对应的位置。 + +// 这里使用另一种全局作用域,这会将单例创建在dontdestroy世界中 +TestScript globalInst = SingleMonoBase.GlobalInstance; +// 如果对象已经被超级单例注册过了,那这个对象就会保持当前的作用域,调用新的作用域也不会使其转移,所以请在一开始就确定单例的作用范围。 ``` ### 隔离绝对自身 -超级单例允许你使用并非传统单例的模式进行声名,谁说单例的泛型必须声名自己了? +超级单例允许你使用并非传统单例的模式进行声名,谁说自己是单例的同时必须单例是自己了? ``` csharp - -public class MyClassA: SingleMonoBase -{ - +public class MyClassB: SingleMonoBase +{ + // 如果想访问自己可以这么做 + public static MyClassB myInstb => InstanceSelf as MyClassB; + + // 否则其他inst方法获取的是 MyClassA的单例 + public static MyClassA myinsta => MyClassB.Instance; } -// 使用带有self的属性来访问 MyClassA -myAclass = MyClassA.InstanceSelf as MyClassA; - -// 不带self的属性则会访问到 MyClassB -myBclass = MyClassA.Instance; +// 顺带一提,可以将两个脚本互为单例,编译器不会报错,就是不知道有什么用。 +public class MyClassA : SingleMonoBase { } +public class MyClassB : SingleMonoBase { } ``` -在`MyClassA`中可以与`MyClassB`完全隔离的用法,不会继承`MyClassB`的任何内容。 +在`MyClassB`中可以与`MyClassB`完全隔离的用法,不会继承`MyClassA`的任何内容。 +但又可以继续使用MyClassA的属性和方法,和普通的单例几乎一样。 + +> 解释一下为什么这么做,你有一个很好用的基类,里面定义了一些你想用的方法,但可惜这些方法都是实例状态下调用的,而且它不能用在你当前的环境下。 +> 比如这个基类是设计给3d场景的,而你的脚本用于ui环境下,基类挂不上,或者不能挂上去。那么可以声名成这样的形式,你的单例仍然是继承自MonoBehaviour,而不是那个基类。 +> 而那个基类则会自动创建,在使用过程中直接调用即可。 ### 代理单例