目前个人已知的bloc方法是三种:
第一种 BlocProvider实现为常规StatefulWidget,使用context.ancestorWidgetOfExactType(),实现bloc。
context.ancestorWidgetOfExactType()是一个为时间复杂度为O(n)的函数,为了检索某种类型的祖先,它将对widget树 做向上导航,从上下文开始,一次递增一个父,直到完成。源码:
@override
Widget ancestorWidgetOfExactType(Type targetType) {
assert(_debugCheckStateIsActiveForAncestorLookup());
Element ancestor = _parent;
while (ancestor != null && ancestor.widget.runtimeType != targetType)
ancestor = ancestor._parent;
return ancestor?.widget;
}
目前新版本的flutter此方法已经过期,但例子中已经有新方法的替换解决方案,接着说回我们的context.ancestorWidgetOfExactType(),如果从上下文到祖先的距离很小(即O(n)结果很少),则可以接受对此函数的调用,否则应该避免,所以才会有我们的第二种方法。
第二种 BlocProvider 实现依赖于StatefulWidget,并结合InheritedWidget,使用context.getElementForInheritedWidgetOfExactType(),实现bloc
由于使用了InheritedWidget,它现在可以调用context.ancestorInheritedElementForWidgetOfExactType()函数,它是一个O(1),这意味着祖先的检索是立即的。源码:
@override
InheritedElement ancestorInheritedElementForWidgetOfExactType(Type targetType) {
assert(_debugCheckStateIsActiveForAncestorLookup());
final InheritedElement ancestor = _inheritedWidgets == null ? null:_inheritedWidgets[targetType];
return ancestor;
}
为什么使用 ancestorInheritedElementForWidgetOfExactType ?
您可能已经注意到我使用 ancestorInheritedElementForWidgetOfExactType 方法而不是通常的 inheritFromWidgetOfExactType 。
原因是我不希望上下文调用的BlocProvider被注册为InheritedWidget的依赖项,因为我不需要它。
目前新版本的flutter此方法已经过期,但例子中已经有新方法的替换解决方案。
目前个人自定义的bloc 会有steSate()重复调用的问题等,官方发布第三方插件:flutter_bloc.
网友评论