我应该在结尾还是开头调用super.initState?



我很困惑在 Flutter 中在哪里称呼super.initSate()?在某些代码示例中,它在开头调用,在其他代码示例中在末尾调用。有区别吗?

我试图用谷歌搜索这个,但没有找到关于这个函数调用位置的任何解释。

哪一个是正确的?

void initState() {
super.initState();    
//DO OTHER STUFF
}

void initState() {    
//DO OTHER STUFF
super.initState();    
}

这对mixins确实很重要(正因为如此,对来说也是如此(

它是Flutter 框架中的一个范例,在覆盖State中的生命周期方法时调用超级方法。这就是为什么即使deactivate也有mustCallSuper注释.
此外,一些mixin期望你在函数中的特定点调用这些生命周期方法的超级方法。

这意味着您应该遵循文档并在dispose方法结束时调用super.dispose,因为框架中的Statemixin期望是这种情况.
例如:TickerProviderStateMixinSingleTickerProviderStateMixin在最后断言super.dispose

在调用 super.dispose(( 之前,必须释放所有 Ticker [..]。

再比如:AutomaticKeepAliveMixin执行initStatedispose中的逻辑。

结论

如果您想轻松安全地将mixin添加到您的State.
此外,请遵循其他生命周期方法的文档(您在State中覆盖的任何方法(,因为框架希望您按照文档中的说明调用超级方法,super.initState开始您的并结束您的super.disposedisposeinitState

因此,您应该执行以下操作:

@override
void initState() {
super.initState();    
// DO YOUR STUFF
}
@override
void dispose() {
// DO YOUR STUFF
super.dispose();
}

但是,这对State并不重要,我将在下面解释,甚至对于mixins,它只对断言很重要,从我能找到的内容来看 - 所以它不会影响您的生产应用程序。

State没关系

我认为巴勃罗·巴雷拉(Pablo Barrera(和CopsOnRoad的前两个答案具有误导性,因为事情的真相是,这真的无关紧要,你不需要看得太远。

super.initStatesuper.disposeState类本身中执行的唯一操作是断言,并且由于assert-语句仅在调试模式下计算,因此一旦构建应用程序(即在生产模式下(就无关紧要。


在下文中,我将指导您完成super.initStatesuper.disposeState中执行的操作,这是当您没有其他mixin时将执行的所有代码。

initState

让我们先看看super.initState中执行的代码(源代码(:

@protected
@mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}

如您所见,只有一个生命周期断言,其目的是确保您的小部件正常工作。因此,只要您在自己的initState中的某个地方调用super.initState,如果您的小部件未按预期工作,您将看到AssertionError。如果您事先采取了一些操作并不重要,因为assert只是为了报告代码中的某些内容是错误的,即使您在方法的最后调用super.initState,您也会看到这一点。

dispose

dispose方法类似(来源(:

@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() {
_debugLifecycleState = _StateLifecycle.defunct;
return true;
}());
}

如您所见,它还仅包含处理调试生命周期检查的断言。这里的第二个assert是一个很好的技巧,因为它确保_debugLifecycleState仅在调试模式下更改(因为assert语句仅在调试模式下执行(.
这意味着只要您在自己的方法中的某个地方调用super.dispose,如果不添加其他功能,您就不会丢失任何价值。

>super.initState()应始终是initState方法的第一行。

从文档中:

initState((:如果重写它,请确保你的方法以调用 super.initState((.

正如您在框架中的类中看到的那样,您应该在初始化小部件后执行所有操作,这意味着在super.initState()之后。

我处理的情况在逻辑上是另一种方式,首先做所有事情,然后调用super.dispose().

@override
void initState() {
super.initState();
// DO STUFF
}
@override
void dispose() {
// DO STUFF
super.dispose();
}

每当将新的有状态小部件添加到小部件树中时,默认情况下都会调用 initState。 现在,super.initState 执行小部件基类的默认实现。如果在 super.initState 之前调用依赖于基类的任何内容,则可能会导致问题。 这就是为什么建议你以这种方式调用 initState:

@override
void initState() {
super.initState();
// DO STUFF
}

最新更新