GFramework/docs/zh-CN/core/lifecycle.md
GeWuYou fb14d7122c docs(style): 更新文档中的命名空间导入格式
- 将所有小写的命名空间导入更正为首字母大写格式
- 统一 GFramework 框架的命名空间引用规范
- 修复 core、ecs、godot 等模块的命名空间导入错误
- 标准化文档示例代码中的 using 语句格式
- 确保所有文档中的命名空间引用保持一致性
- 更新 global using 语句以匹配正确的命名空间格式
2026-03-10 07:18:49 +08:00

11 KiB
Raw Permalink Blame History

title, description
title description
生命周期管理 生命周期管理提供了标准化的组件初始化和销毁机制,确保资源的正确管理和释放。

生命周期管理

概述

生命周期管理是 GFramework 中用于管理组件初始化和销毁的核心机制。通过实现标准的生命周期接口,组件可以在适当的时机执行初始化逻辑和资源清理,确保系统的稳定性和资源的有效管理。

GFramework 提供了同步和异步两套生命周期接口,适用于不同的使用场景。架构会自动管理所有注册组件的生命周期,开发者只需实现相应的接口即可。

主要特性

  • 标准化的初始化和销毁流程
  • 支持同步和异步操作
  • 自动生命周期管理
  • 按注册顺序初始化,按逆序销毁
  • 与架构系统深度集成

核心概念

生命周期接口层次

GFramework 提供了一套完整的生命周期接口:

// 同步接口
public interface IInitializable
{
    void Initialize();
}

public interface IDestroyable
{
    void Destroy();
}

public interface ILifecycle : IInitializable, IDestroyable
{
}

// 异步接口
public interface IAsyncInitializable
{
    Task InitializeAsync();
}

public interface IAsyncDestroyable
{
    ValueTask DestroyAsync();
}

public interface IAsyncLifecycle : IAsyncInitializable, IAsyncDestroyable
{
}

初始化阶段

组件在注册到架构后会自动进行初始化:

public class PlayerModel : AbstractModel
{
    protected override void OnInit()
    {
        // 初始化逻辑
        Console.WriteLine("PlayerModel 初始化");
    }
}

销毁阶段

当架构销毁时,所有实现了 IDestroyable 的组件会按注册的逆序被销毁:

public class GameSystem : AbstractSystem
{
    public void Destroy()
    {
        // 清理资源
        Console.WriteLine("GameSystem 销毁");
    }
}

基本用法

实现同步生命周期

最常见的方式是继承框架提供的抽象基类:

using GFramework.Core.Model;

public class InventoryModel : AbstractModel
{
    private List<Item> _items = new();

    protected override void OnInit()
    {
        // 初始化库存
        _items = new List<Item>();
        Console.WriteLine("库存系统已初始化");
    }
}

实现销毁逻辑

对于需要清理资源的组件,实现 IDestroyable 接口:

using GFramework.Core.Abstractions.System;
using GFramework.Core.Abstractions.Lifecycle;

public class AudioSystem : ISystem, IDestroyable
{
    private AudioEngine _engine;

    public void Initialize()
    {
        _engine = new AudioEngine();
        _engine.Start();
    }

    public void Destroy()
    {
        // 清理音频资源
        _engine?.Stop();
        _engine?.Dispose();
        _engine = null;
    }
}

在架构中注册

组件注册后,架构会自动管理其生命周期:

public class GameArchitecture : Architecture
{
    protected override void Init()
    {
        // 注册顺序Model -> System -> Utility
        RegisterModel(new PlayerModel());      // 1. 初始化
        RegisterModel(new InventoryModel());   // 2. 初始化
        RegisterSystem(new AudioSystem());     // 3. 初始化

        // 销毁顺序会自动反转:
        // AudioSystem -> InventoryModel -> PlayerModel
    }
}

高级用法

异步初始化

对于需要异步操作的组件(如加载配置、连接数据库),使用异步生命周期:

using GFramework.Core.Abstractions.Lifecycle;
using GFramework.Core.Abstractions.System;

public class ConfigurationSystem : ISystem, IAsyncInitializable
{
    private Configuration _config;

    public async Task InitializeAsync()
    {
        // 异步加载配置文件
        _config = await LoadConfigurationAsync();
        Console.WriteLine("配置已加载");
    }

    private async Task<Configuration> LoadConfigurationAsync()
    {
        await Task.Delay(100); // 模拟异步操作
        return new Configuration();
    }
}

异步销毁

对于需要异步清理的资源(如关闭网络连接、保存数据):

using GFramework.Core.Abstractions.Lifecycle;

public class NetworkSystem : ISystem, IAsyncDestroyable
{
    private NetworkClient _client;

    public void Initialize()
    {
        _client = new NetworkClient();
    }

    public async ValueTask DestroyAsync()
    {
        // 异步关闭连接
        if (_client != null)
        {
            await _client.DisconnectAsync();
            await _client.DisposeAsync();
        }
        Console.WriteLine("网络连接已关闭");
    }
}

完整异步生命周期

同时实现异步初始化和销毁:

public class DatabaseSystem : ISystem, IAsyncLifecycle
{
    private DatabaseConnection _connection;

    public async Task InitializeAsync()
    {
        // 异步连接数据库
        _connection = new DatabaseConnection();
        await _connection.ConnectAsync("connection-string");
        Console.WriteLine("数据库已连接");
    }

    public async ValueTask DestroyAsync()
    {
        // 异步关闭数据库连接
        if (_connection != null)
        {
            await _connection.CloseAsync();
            await _connection.DisposeAsync();
        }
        Console.WriteLine("数据库连接已关闭");
    }
}

生命周期钩子

监听架构的生命周期阶段:

using GFramework.Core.Abstractions.Enums;

public class AnalyticsSystem : AbstractSystem
{
    protected override void OnInit()
    {
        Console.WriteLine("分析系统初始化");
    }

    public override void OnArchitecturePhase(ArchitecturePhase phase)
    {
        switch (phase)
        {
            case ArchitecturePhase.Initializing:
                Console.WriteLine("架构正在初始化");
                break;
            case ArchitecturePhase.Ready:
                Console.WriteLine("架构已就绪");
                StartTracking();
                break;
            case ArchitecturePhase.Destroying:
                Console.WriteLine("架构正在销毁");
                StopTracking();
                break;
        }
    }

    private void StartTracking() { }
    private void StopTracking() { }
}

最佳实践

  1. 优先使用抽象基类:继承 AbstractModelAbstractSystem 等基类,它们已经实现了生命周期接口

     public class MyModel : AbstractModel { }
     public class MyModel : IModel, IInitializable { }
    
  2. 初始化顺序很重要:按依赖关系注册组件,被依赖的组件先注册

    protected override void Init()
    {
        RegisterModel(new ConfigModel());      // 先注册配置
        RegisterModel(new PlayerModel());      // 再注册依赖配置的模型
        RegisterSystem(new GameplaySystem());  // 最后注册系统
    }
    
  3. 销毁时释放资源:实现 Destroy() 方法清理非托管资源

    public void Destroy()
    {
        // 释放事件订阅
        _eventBus.Unsubscribe<GameEvent>(OnGameEvent);
    
        // 释放非托管资源
        _nativeHandle?.Dispose();
    
        // 清空引用
        _cache?.Clear();
    }
    
  4. 异步操作使用异步接口:避免在同步方法中阻塞异步操作

     public async Task InitializeAsync() { await LoadDataAsync(); }
     public void Initialize() { LoadDataAsync().Wait(); } // 可能死锁
    
  5. 避免在初始化中访问其他组件:初始化顺序可能导致组件尚未就绪

     protected override void OnInit()
    {
        var system = this.GetSystem<OtherSystem>(); // 可能尚未初始化
    }
    
     public override void OnArchitecturePhase(ArchitecturePhase phase)
    {
        if (phase == ArchitecturePhase.Ready)
        {
            var system = this.GetSystem<OtherSystem>(); // 安全
        }
    }
    
  6. 使用 OnArchitecturePhase 处理跨组件依赖:在 Ready 阶段访问其他组件

    public override void OnArchitecturePhase(ArchitecturePhase phase)
    {
        if (phase == ArchitecturePhase.Ready)
        {
            // 此时所有组件都已初始化完成
            var config = this.GetModel<ConfigModel>();
            ApplyConfiguration(config);
        }
    }
    

常见问题

问题:什么时候使用同步 vs 异步生命周期?

解答

  • 同步:简单的初始化逻辑,如创建对象、设置默认值
  • 异步:需要 I/O 操作的场景,如加载文件、网络请求、数据库连接
// 同步:简单初始化
public class ScoreModel : AbstractModel
{
    protected override void OnInit()
    {
        Score = 0; // 简单赋值
    }
}

// 异步:需要 I/O
public class SaveSystem : ISystem, IAsyncInitializable
{
    public async Task InitializeAsync()
    {
        await LoadSaveDataAsync(); // 文件 I/O
    }
}

问题:组件的初始化和销毁顺序是什么?

解答

  • 初始化顺序:按注册顺序(先注册先初始化)
  • 销毁顺序:按注册的逆序(后注册先销毁)
protected override void Init()
{
    RegisterModel(new A());    // 1. 初始化3. 销毁
    RegisterModel(new B());    // 2. 初始化2. 销毁
    RegisterSystem(new C());   // 3. 初始化1. 销毁
}

问题:如何在初始化时访问其他组件?

解答 不要在 OnInit() 中访问其他组件,使用 OnArchitecturePhase() 在 Ready 阶段访问:

public class DependentSystem : AbstractSystem
{
    protected override void OnInit()
    {
        // ✗ 不要在这里访问其他组件
    }

    public override void OnArchitecturePhase(ArchitecturePhase phase)
    {
        if (phase == ArchitecturePhase.Ready)
        {
            // ✓ 在这里安全访问其他组件
            var config = this.GetModel<ConfigModel>();
        }
    }
}

问题Destroy() 方法一定会被调用吗?

解答 只有在正常销毁架构时才会调用。如果应用程序崩溃或被强制终止,Destroy() 可能不会被调用。因此:

  • 不要依赖 Destroy() 保存关键数据
  • 使用自动保存机制保护重要数据
  • 非托管资源应该实现 IDisposable 模式

问题:可以在 Destroy() 中访问其他组件吗?

解答 不推荐。销毁时其他组件可能已经被销毁。如果必须访问,确保检查组件是否仍然可用:

public void Destroy()
{
    // ✗ 不安全
    var system = this.GetSystem<OtherSystem>();
    system.DoSomething();

    // ✓ 安全
    try
    {
        var system = this.GetSystem<OtherSystem>();
        system?.DoSomething();
    }
    catch
    {
        // 组件可能已销毁
    }
}

相关文档