“不要跨越异步间隙使用 ‘BuildContext’ 的警告” 这个警告是无用的吗?

huangapple go评论97阅读模式
英文:

Is the warning "Don't use 'BuildContext's across async gaps" a useless warning?

问题

考虑这个第一个例子:

Future<void> initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  Navigator.of(context).pop(); // 不要在异步间隙中使用 'BuildContext'。
}

现在,考虑这个第二个例子:

Future<void> initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  exitScreen();
  // exitScreenAsync();
}

void exitScreen() {
  Navigator.of(context).pop(); // 现在编译器满意了。
}

Future<void> exitScreenAsync() async {
  Navigator.of(context).pop(); // 编译器仍然满意吗?
}

正如您所看到的,这两个例子之间唯一的区别是第二个例子通过调用函数来弹出导航器,而第一个例子没有。然而,在第二个例子中,编译器是完全满意的,没有显示任何警告。

我觉得这个警告有点愚蠢和无意义。为什么我必须将使用 'BuildContext' 的代码部分移动到一个代理函数中,只是为了摆脱这个警告呢?

英文:

Consider this first example:

Future&lt;void&gt; initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  Navigator.of(context).pop(); // Don&#39;t use &#39;BuildContext&#39;s across async gaps.
}

Now, consider this second example:

Future&lt;void&gt; initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  exitScreen();
  // exitScreenAsync();
}

void exitScreen() {
  Navigator.of(context).pop(); // The compiler is satisfied now.
}

Future&lt;void&gt; exitScreenAsync() async {
  Navigator.of(context).pop(); // The compiler remains satisfied?
}

As you can see, the only difference between these two examples is that the the second example is popping the navigator by calling a function while the first one is not. However, with the second exmaple the compiler is perfectly fine and no warning is displayed.

I find this warning a bit stupid and meaningless. Why do I have to move the code section that makes use of the BuildContext across async gaps to a proxy function just to get rid of this warning?

答案1

得分: 1

这个警告并不是无用的警告。
问题是,在等待后,每次使用 BuildContext 都会显示这个警告。这个警告之所以出现是因为在等待之后使用 BuildContext 可能会在小部件被销毁后发生。这种情况下,上下文将不再存在,应用甚至可能因此崩溃。请查看官方的 lint 文档:

if (context.mounted) Navigator.of(context).pop();
英文:

No it's not useless warning.
The problem is that after an await, every use of the BuildContext will show this warning. This warning happens because using a BuildContext after an await could happen after the widget is disposed of. This way, the context wouldn't exist anymore and the app could even crash because of this. Check out the official lint documentation:

if (context.mounted) Navigator.of(context).pop();

答案2

得分: 0

你不应该忽略这个警告,因为它可能导致运行时错误。在异步函数期间,小部件可能会被卸载或销毁,导致无效的构建上下文。

在异步调用之后,并在使用 context 之前,每次都要检查小部件是否已挂载,像这样:

Future<void> initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  if (mounted) {
    Navigator.of(context).pop(); 
  }
}

警告将消失,但这次您将受到保护,不会使用无效的上下文。要使用 mounted,您必须位于具有此属性的小部件类内部。

英文:

You should not ignore this warning because it can lead to a runtime error. During the async function the widget can be dismounted or destroyed, resulting in an invalid build context.

Check if the widget is mounted after the async calls and before using the context every time, like this:

Future&lt;void&gt; initializeServices() async {
  await notificationService.begin();
  await geotrackingService.begin();
  if (mounted) {
    Navigator.of(context).pop(); 
  }
}

The warning will disappear but this time you are protected against using an invalid context. In order to use mounted you must be inside a widget class which has this property.

答案3

得分: 0

你的 exitScreen 不是一个 async 方法,这就是为什么编译器满意的原因。initializeServices() 是一个 async 方法,它包含一些未来需要等待的内容,然后才能使用上下文来退出,这就是为什么它在抱怨。

如果你仍然希望使用 exitScreen,最好检查是否已挂载,如下所示:

if (mounted) exitScreen();
英文:

Your exitScreen is not an async method, that's why compiler is satisfied. The initializeServices() is an async method, it contains some future to be awaited before it can use context to pop, that's why it was complaining.

If you still wish to use exitScreen it would be proper to check mounted like

if(mounted) exitScreen();

huangapple
  • 本文由 发表于 2023年5月25日 22:15:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76333288.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定