初始化方法只调用一次 c#
本文关键字:一次 方法 调用 初始化 | 更新日期: 2023-09-27 18:33:53
嗯,我知道这个问题已经被问过了,我也碰巧知道最简单的方法。
现在我的问题更多的是关于你关于是否有更好方法的建议。
我希望在启用或创建组件时仅调用一次我的方法。请参阅我可以创建一个组件但将其禁用,然后当我第一次启用它时,我希望调用 Init 方法。组件包含在"附加"对象中。
所以我有组件
internal bool _runOnce;
然后我有主对象
List<Component> _listComp = new List<Component>();
void Update(){
foreach(Component c in _listComp){
if(!c.enable)continue;
if(c._runOnce){
c.Init();
c._runOnce = false;
}
c.Update();
}
}
我主要担心的是,对_runOnce的检查将针对每个对象上的每个组件进行每一帧。我知道这只是一个布尔校验,一文不值,但我只是问是否有人会知道比这更好的模式。
谢谢
您还可以仅列出已启用的组件。
List<Component> _listEnabled = _listComp.Where(item => (item.enable == true));
foreach(Component c in _listEnabled ){
if(c._runOnce){
c.Init(); // if at all possible, _runOnce should be set to false
c._runOnce = false; // IN THE OBJECT, after calling Init();
}
c.Update();
}
我会质疑Update()
是否是Init()
动态组件的合适生命周期设计。
似乎有一个名义上称为GameObject.ActivateComponent(AbstractComponent C)
调用C.Init()
的方法更有意义,AbstractComponent::Init
调用OnInit
,这是组件覆盖和实现的。 AbstractComponent::Init
会进行_runonce检查并提前返回。这是一个方法调用,但它使代码更加抽象,并且如果您需要为"这是我第二次或以后初始化"提供钩子,则可以选择扩展为稍后具有OnReinitialize
代码路径。(比如说,一个统计重置选项...
对于Update()
来说,探测像"runonce"这样的实现细节来了解Component
的初始化状态似乎绝对是错误的。
List<Component> _listComp = new List<Component>();
void Update(){
foreach(Component c in _listComp){
c.Update();
}
}
抽象组件
public bool Enable { get;set;}
private bool _initialized = false;
void Update(){
if (!Enable) return;
Init();
OnUpdate();
}
protected virtual void OnUpdate()
{
// filled in by user script
}
private void Init()
{
if (_initialized) return;
OnInit();
_initialized = true;
}
protected virtual void OnInit()
{
// filled in by user script
}
My main concern is that the check for _runOnce will happen every frame for every component on each object.
由此,我假设您经常打电话给Update
。我担心的是组件的Update
方法,它很可能比布尔检查贵得多。这就是所谓的微优化:你把很多精力放在根本不成问题的事情上。
但是,我建议封装初始化。您的MainObject
不需要对此一无所知。 _runOnce
应该是组件的私有成员,enable
应该是属性(顺便说一句:_runOnce
应该在某处初始化为 true)。每次启用组件时,您都可以检查_runOnce
并在需要时调用初始化:
public class MyComponent
{
private bool _isInitialized; // I think this is a better name than _runOnce
private bool _enable;
public bool Enable
{
get
{
return _enable;
}
set
{
if (_enable == value)
{
return;
}
if (value == true && !_isInitialized)
{
Init();
}
_enable = value;
}
}
private void Init()
{
// initialization logic here ...
_isInitialized = true;
}
}
另一个想法是将初始化推迟到 Update
方法。这基本上是你已经拥有的,但在面向对象的设计中:
public void Update()
{
if (_enable && !_isInitialized)
{
Init();
}
// update logic here ...
}
组件的常规构造函数呢?
public Component()
{
Init();
}