在Flutter中,State的生命周期可以分为以下几个阶段:创建、更新和销毁。在这些阶段中,State会触发一系列生命周期方法来响应不同的事件。
- 创建阶段
在创建阶段中,State会触发以下生命周期方法:
- initState:初始化State对象,通常用于初始化一些状态和数据
- didChangeDependencies:在State对象依赖的对象发生变化时调用,通常用于获取依赖对象并更新状态
- build:构建UI界面
- 更新阶段
在更新阶段中,State会触发以下生命周期方法:
- didUpdateWidget:在Widget属性发生变化时调用,通常用于更新状态
- setState:用于更新State对象的状态
- build:构建UI界面
- 销毁阶段
在销毁阶段中,State会触发以下生命周期方法:
- deactivate:暂时从视图树中移除,通常用于释放一些资源
- dispose:永久从视图树中移除,通常用于释放所有资源
下面我们来详细了解一下每个生命周期方法的作用:
- initState
这个方法会在State对象被创建后调用,用于初始化State对象。在这个方法中,我们通常可以进行一些状态和数据的初始化操作。
- didChangeDependencies
这个方法会在State对象依赖的对象发生变化时调用,例如父Widget发生变化时。在这个方法中,我们通常可以获取依赖对象并更新状态。
- build
这个方法会在创建阶段和更新阶段都会被调用,用于构建UI界面。在这个方法中,我们通常会根据当前的状态和数据来构建UI。
- didUpdateWidget
这个方法会在Widget属性发生变化时调用,例如父Widget的属性发生变化时。在这个方法中,我们通常可以更新一些状态和数据。
- setState
这个方法会在State对象的状态发生变化时调用,用于更新状态。在这个方法中,我们通常可以更新一些状态和数据,并触发UI的重新构建。
- deactivate
这个方法会在State对象暂时从视图树中移除时调用,例如当页面被覆盖时。在这个方法中,我们通常可以释放一些资源,以避免内存泄漏。
- dispose
这个方法会在State对象永久从视图树中移除时调用,例如当页面被销毁时。在这个方法中,我们通常可以释放所有资源,以避免内存泄漏。
总之,了解State的生命周期是非常重要的,可以帮助我们更好地管理UI的状态和资源,以确保应用程序的高效性和稳定性。
didUpdateWidget方法是在更新阶段中调用的,当StatefulWidget的父Widget属性发生变化时会触发该方法。
源码实现:
复制dart
@protected
@mustCallSuper
void didUpdateWidget(covariant T oldWidget) {
assert(() {
if (debugPrintRebuildDirtyWidgets)
debugPrint('didUpdateWidget ${widget.runtimeType}');
return true;
}());
}
可以看到,didUpdateWidget方法中调用了assert方法,用于在开发模式下输出调试信息。
同时,该方法还接收一个oldWidget参数,用于获取旧的Widget对象。我们可以通过比较旧的Widget对象和新的Widget对象来判断Widget属性是否发生了变化,从而更新一些状态和数据。
总之,理解生命周期方法的源码实现可以帮助我们更好地管理UI状态和资源,以确保应用程序的高效性和稳定性。
除了didUpdateWidget方法,其他生命周期方法的源码实现也是类似的。让我们以StatefulWidget的生命周期方法initState为例,来进一步解析其源码实现。
initState方法是在创建阶段中调用的,用于初始化State对象。在这个方法中,我们通常可以进行一些状态和数据的初始化操作。
源码实现:
复制dart
@protected
@mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
if (widget._debugLifecycleState != null)
widget._debugLifecycleState!._created(this);
if (widget.initializer != null) {
final dynamic result = widget.initializer!();
assert(() {
if (result is Future) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary(
'State.initState() returned a Future.'
),
ErrorDescription(
'State.initState() must be a void method, not a Future.'
),
]);
}
if (result is FutureOr) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary(
'State.initState() returned a FutureOr<dynamic> type.'
),
ErrorDescription(
'State.initState() must be a void method, not a FutureOr<dynamic> type.'
),
]);
}
return true;
}());
}
}
我们可以看到,initState方法中也调用了assert方法,用于在开发模式下输出调试信息。
同时,该方法还判断了State对象的生命周期状态是否为created。
在State对象的整个生命周期中,其生命周期状态会随着不同的事件发生而改变,而_created状态表示State对象已经被创建。
在这个方法中,我们还可以通过widget对象的initializer属性来初始化State对象的状态和数据。
initializer属性是一个无参的闭包函数,它返回一个动态类型的值,可以用于在初始化State对象时执行一些逻辑操作。
didChangeDependencies方法是在创建阶段中调用的,当State对象依赖的对象发生变化时会触发该方法。在这个方法中,我们通常可以获取依赖对象并更新状态。
源码实现:
复制dart
@protected
@mustCallSuper
void didChangeDependencies() {
assert(_debugLifecycleState == _StateLifecycle.created);
if (_dependencies != null)
_dependencies!.didChangeDependencies();
}
我们可以看到,didChangeDependencies方法中也调用了assert方法,用于在开发模式下输出调试信息。
同时,该方法还判断了State对象的生命周期状态是否为created。在State对象的整个生命周期中,其生命周期状态会随着不同的事件发生而改变,而_created状态表示State对象已经被创建。
在这个方法中,我们还可以获取依赖对象并更新状态。在Flutter中,State对象可以依赖于其他对象,例如InheritedWidget、MediaQuery等。当这些依赖对象发生变化时,didChangeDependencies方法就会被调用,我们可以在这个方法中获取新的依赖对象并更新状态,以保持UI的正确性和一致性。
原文链接:https://juejin.cn/post/7221821674747117605 作者:君不见999