1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

flutterのmarkNeedsBuildとは何か?

Posted at

markNeedsBuild「再構築、必要、マークつけとくから頼んだ🙋‍♂️」

Elementが「再構築(rebuild)が必要(Needs)になりました🙋‍♂️」とrebuildを希望します。

rebuildを希望するElementは自身にマーク(mark)をつける決まりになっています。
(ここからは再構築とrebuildはrebuildで統一して表現します)

解説していきます。

マークとは具体的に何?

=> Elementが持つpropertyのdirty(bool)のことです
https://api.flutter.dev/flutter/widgets/Element-class.html#:~:text=read%2Donly-,dirty,-%E2%86%92%20bool

dirtyとは?

=> Elementの持つpropertyで型はboolです。

要素が再構築が必要であるとマークされている場合はtrueを返します。(google翻訳)
https://api.flutter.dev/flutter/widgets/Element/dirty.html

雰囲気を実際のコードで伝えます

class Element {
    //...
    /// Returns true if the element has been marked as needing rebuilding.
    bool get dirty => _dirty;
    bool _dirty = true;
    //....
}

正確なコードはこちら
https://github.com/flutter/flutter/blob/57d522287686792964545692862ba3128b572b61/packages/flutter/lib/src/widgets/framework.dart#L4402

ここまでがmarkNeedsBuildの簡単な説明です。


Q&A形式で理解を深める

ここからはmarkNeedsBuildが
flutterの他の機能とどのように関わり
何を実現するかなどをQ&A形式で書いていきます

rebuildは誰に要請するの?

=> BuildOwnerクラスです。

BuildOwnerクラスとは何?

=> Elementツリーを管理するクラスです

rebuildはBuildOwnerクラスのどこでされるの?

=> BuildOwnerのbuildScopeメソッドです

フレーム毎に呼ばれるdrawFrameがbuildScopeを呼び出すようです。

markNeedsBuildのメソッドの中身は?何をしているの?

=> dirtyをtrueにしBuildOwnerのクラスのscheduleBuildForメソッドを呼びます。引数は自身(Element)

まずBuildOwnerのクラスのscheduleBuildForメソッドの説明をします

=> _dirtyElementsというprivateなpropertyに引数として渡されたElementを追加します
_dirtyElementsとはrebuild待ちElementリストのことです。

(まとめます)markNeedsBuildのメソッドの中身は?何をしているの?

ElementのmarkNeedsBuildメソッドの処理の流れを見てみましょう

1,ElementクラスのmarkNeedsBuildメソッドは
BuildOwnerクラスのscheduleBuildForメソッドを呼び出します。
引数として自身(Element)を渡します。

2,呼び出されたBuildOwnerクラスのscheduleBuildForメソッドは渡されたElementを
rebuild待ちElementリストである_dirtyElementsプロパティに追加します。

少々複雑な説明になってしまったので
最低限必要な部分のみを切り出した簡単なコードを見てみましょう

Element

//色々と省略...
void markNeedsBuild() {
 //色々と省略...
 _dirty = true;  
 owner!.scheduleBuildFor(this); //1
}

BuildOwner

//色々と省略...
final List<Element> _dirtyElements = <Element>[];
void scheduleBuildFor(Element element) {
//色々と省略...
_dirtyElements.add(element); //2
}

その_dirtyElementsはその後どのように使われるの?

=> フレーム毎に呼ばれるWidgetBindingdrawFrameがBuildOwnerのbuildScopeを呼び出しrebuild待ちElementリストである_dirtyElementsを順に取り出しrebuildしていきます

buildScopeのコードを見てみる(抜粋し4行にした)

framework.dart
for (final Element element in _dirtyElements) {
//...
 try {
        element.rebuild();
      } catch (e, stack) {
        // ...
      }
//...
}

気になる方はgithubで確認してみて下さい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?