调用 setState()必须是没有调用过 dispose()方法,不然出错,可通过mounted
属性来判断调用此方法是否合法。
if (mounted) {
setState(() {});
}
清晰的看到在framework.dart内setstate方法除了一些条件判断就是:
_element.markNeedsBuild();
那我们看看markNeedsBuild。
Element 类 markNeedsBuild方法
void markNeedsBuild() {
assert(_debugLifecycleState != _ElementLifecycle.defunct);
if (!_active)
return;//返回
...
if (dirty)
return;
_dirty = true;
//调用scheduleBuildFor方法
owner.scheduleBuildFor(this);
}
将 element 元素标记为“脏”,并把它添加到全局的“脏”链表里,以便在下一帧更新信号时更新.
- 这里的“
脏
”链表是待更新的链表,更新过后就不“脏”了。 - 由于一帧做两次更新有点低效,所以在
_active=false
的时候直接返回。
那我们看看本方法最后调用的scheduleBuildFor方法。
BuildOwner 类 scheduleBuildFor方法
BuildOwner
类是widget framework
的管理类,它跟踪那些需要重新构建的 widget。
void scheduleBuildFor(Element element) {
...
if (element._inDirtyList) {
...
_dirtyElementsNeedsResorting = true;
return;
}
if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled();//回调
}
_dirtyElements.add(element);//把element加入脏元素链表
element._inDirtyList = true;
assert(() {
if (debugPrintScheduleBuildForStacks)
debugPrint('...dirty list is now: $_dirtyElements');
return true;
}());
}
把一个 element 添加到 _dirtyElements 链表,以便当Widget