Flutter & Dart:安装的目的是什么?

Pun*_*any 13 dart flutter

我看到这个mounted语法。它是做什么用的?你能给我样品吗?

Wil*_*son 40

TL;DR:如果小部件具有状态,则它会被安装。如果小部件不再被安装,即它已被关闭或处置,则其状态不能再被更新。因此,我们检查一个小部件是否已安装以确定其状态是否仍然可以更新。

挂载是创建 StatefulWidget 状态并将其附加到 BuildContext 的过程。

举个例子:

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  @override
  Widget build(BuildContext context) {
    return Container(
      
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

createState()当调用该方法时,小部件将被分配其状态 (_ExampleState) 。

一旦分配了状态,小部件就会被安装。

为什么这很重要?

当在 a 的 dispose 方法中卸载小部件时StatefulWidget,它会丢失其状态。当它不再在树中时就会发生这种情况。即,它已被关闭,或不再存在。

 @override
  void unmount() {
    super.unmount();
    state.dispose();
    assert(() {
      if (state._debugLifecycleState == _StateLifecycle.defunct)
        return true;
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('${state.runtimeType}.dispose failed to call super.dispose.'),
        ErrorDescription(
          'dispose() implementations must always call their superclass dispose() method, to ensure '
         'that all the resources used by the widget are fully released.'
        ),
      ]);
    }());

    // This is the key
    state._element = null;
  }
Run Code Online (Sandbox Code Playgroud)

这基本上意味着状态无法更新并且 setState 无法再调用。因此,当您检查小部件是否已安装时,您正在检查其状态是否仍然可以更新。

使用案例:

回到我们的 Stateful Widget 示例,假设我们有一个数字想要在 Widget 创建后 30 秒更新。

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  int count = 0;

  @override
  void initState() {
    Future.delayed(const Duration(seconds: 30), () {
      setState(() => count = 5);
    });
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Text('count $count'),
    ));
  }
}
Run Code Online (Sandbox Code Playgroud)

只要小部件被处理或关闭,我们的代码就可以正常工作。如果它被处理掉,我们会得到著名的错误:

setState() called after dispose()
Run Code Online (Sandbox Code Playgroud)

为了防止这种情况,我们所要做的就是在更新之前检查我们的小部件是否仍然具有状态。

  @override
  void initState() {
    Future.delayed(const Duration(seconds: 30), () {
      if (mounted) setState(() => count = 5);
    });
    super.initState();
  }
Run Code Online (Sandbox Code Playgroud)