StatefulWidget 中的以下 var 初始化位置有什么区别?

What is the difference between the following var initialization positions in a StatefulWidget?

我想知道在 StatefulWidget 的情况下在哪里声明和初始化变量。似乎有几种方法可以做到这一点,但是否存在差异、任何指导方针或最佳实践方法?

我创建了以下示例,但除了执行热重载时,variable i 失去了它的值外,找不到任何区别并再次归零。

我读了this,但是里面有很多自相矛盾的评论。

class Sample extends StatefulWidget {
  int i=0;
  late Object object1 = Get.put(Object());
 
  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {
  int j = 0;
  late Object object2;

  @override
  void initState() {
    i=5;
    j=5;
    object1.param="value123";
    object2=Get.put(Object());
    object2.param="value123";
  }

  @override
  Widget build(BuildContext context) {

  }
}

首先,如果您 运行 在模拟器上使用您的应用程序,您确实找不到任何差异。但是,这种观察是巨大的误导!

小部件 class 中声明的变量无论是否初始化,在 [=24= 的情况下 未持久化 ]小部件娱乐。 StatefulWidgets (and all Widget subclasses) are thrown away and rebuilt whenever configuration changes. 幸运的是,您可以在测试应用程序时通过对小部件执行热重载来强制执行小部件重新创建。以确保正确的行为。

如果要声明应该持久化的变量(状态数据),请确保将它们放在状态 class 中,如上面的代码示例中的 int j . 对于无法在声明语句中初始化的变量,请使用 initState()

为什么 object1 保留其数据?

很简单,因为如果 Object 已经存在,GetX 将不会重新创建一个新的 Object 实例。每次重建 Widget 时,它都会 return 返回旧实例。这就是为什么在 object1 和 object2 声明位置的情况下没有区别。

在撰写此答案时,如果您不使用绑定,则必须手动调用 Get.delete<>() 才能处理控制器。