Getx:生命周期与手动删除

  1. GetX的生命周期
    1. 创建(onInit)
    2. 就绪(onReady)
    3. 销毁(onClose)
    4. 内存中删除(Get.delete)
    5. 控制器不会自动销毁
    6. 生命周期图
  2. 移动端应用的内存生命周期

GetX的生命周期

在 GetX 里,Controller 是通过 Get.put()Get.lazyPut()GetBuilder(init:...)GetView/GetWidget 等方式注入的。它们的生命周期分为以下几个阶段:

创建(onInit)

当你第一次用 Get.put()Get.lazyPut()GetBuilder(init: Controller()) 创建控制器时:

  • Controller 实例会被加入到 GetInstance 容器中。
  • 立刻触发 onInit() 回调(如果重写了)。
class MyController extends GetxController {
  @override
  void onInit() {
    super.onInit();
    print('onInit');
  }
}

就绪(onReady)

Controller 绑定到界面后会调用 onReady()

常用于需要等 UI 渲染完成后再调用的逻辑(如弹窗、网络请求)。

@override
void onReady() {
  super.onReady();
  print('onReady');
}

销毁(onClose)

  • 当控制器被从容器中移除时会调用 onClose()
  • 在这里清理资源、取消定时器、关闭流等。
@override
void onClose() {
  print('onClose');
  super.onClose();
}

内存中删除(Get.delete)

Get.delete<MyController>() 会真正移除这个实例,让它完全不再被缓存。

控制器不会自动销毁

GetX 的控制器默认不会自动销毁,这点和很多人直觉相反。常见几种情况:

情况 会不会自动销毁? 说明
Get.put(MyController()) ❌ 不会 必须手动 Get.delete<MyController>()
Get.lazyPut(() => MyController()) ❌ 不会 除非你设置 fenix: true(会在下次需要时重建)
GetBuilder(init: MyController()) ⚠️ 不会 除非你设置 autoRemove: true
GetView<MyController> ❌ 不会 它只是通过 Get.find() 获取,不会创建也不会销毁
Get.put(MyController(), permanent: true) ❌ 永不销毁 整个 App 生命周期都保留

所以你必须手动调用

Get.delete<MyController>(tag: tag);

或者在 GetBuilder 上开启:这样当 Widget dispose 时,控制器也会跟着销毁。

GetBuilder<MyController>(
  init: MyController(),
  autoRemove: true,
  builder: ...
)

如果你使用了 tag 创建多个同类控制器:Get.put(MyController(), tag: 'abc');

销毁时也必须带上同样的 tag:Get.delete<MyController>(tag: 'abc');

否则 Get 容器不会找到它。

生命周期图

flowchart TD
    A[创建 Controller
Get.put / Get.lazyPut / init] --> B["onInit()"] B --> C[绑定到界面] C --> D["onReady()"] D --> E[页面运行中
使用阶段] E --> F{页面被销毁?} F -- 否 --> E F -- 是 --> G{autoRemove 或 delete?} G -- 否 --> E G -- 是 --> H["onClose()"] H --> I["Get.delete() 移除内存"]

移动端应用的内存生命周期

当用户 彻底退出 App(杀进程)

  • 应用所在的 Dart VM 和 Flutter 引擎会被销毁
  • 所有内存(包括 GetX 管理的控制器实例)都会被操作系统回收
  • 不会存在真正意义上的“内存泄漏”

当用户只是 返回桌面 / 切到后台

  • 应用还在内存中挂起(保活)
  • 所有控制器依旧存在于内存里
  • 如果你反复打开多个商品详情页,每次都创建新的控制器实例(还用 UniqueKey()),就会暂时性地占用越来越多的内存
  • 系统在内存吃紧时才会杀掉你的进程来释放资源

【重点】

  • 「内存泄漏」在移动端更多是指在应用仍存活时一直涨内存不释放,而不是退出后残留。
  • 所以:用户关闭程序后自然会清空所有控制器实例,不会造成永久占用。
  • 在应用运行期间,如果你不停 push 商品详情页并使用 UniqueKey() 生成新 tag,又不 Get.delete()短期内会越来越占内存,直到被系统强杀。

×

喜欢就点赞,疼爱就打赏