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(),短期内会越来越占内存,直到被系统强杀。