当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Dart Finalizable用法及代码示例


dart:ffi 库中Finalizable 类的用法介绍如下。

不应过早完成的对象的标记接口。

任何具有includes Finalizable 的静态类型的局部变量都保证是活动的,直到执行退出该变量在范围内的代码块。

类型 includes Finalizable 如果有的话

  • 该类型是 Finalizable 的非 Never 子类型,或
  • 类型是 T?FutureOr<T> 其中 T 包括 Finalizable

换句话说,当一个对象被这样的变量引用时,它保证not被认为是不可达的,并且变量本身在其作用域的整个持续时间内被认为是活动的,即使在它最后一次引用之后也是如此。

Without this marker interface on the variable's type, a variable's value might be garbage collected before the surrounding scope has been completely executed, as long as the variable is definitely not referenced again. That can, in turn, trigger a NativeFinalizer to perform a callback. When the variable's type includes Finalizable, The NativeFinalizer callback is prevented from running until the current code using that variable is complete.

例如,finalizablesomeNativeCall 执行期间保持活动状态:

void myFunction() {
  final finalizable = MyFinalizable(Pointer.fromAddress(0));
  someNativeCall(finalizable.nativeResource);
}

void someNativeCall(Pointer nativeResource) {
  // ..
}

class MyFinalizable implements Finalizable {
  final Pointer nativeResource;

  MyFinalizable(this.nativeResource);
}

实现Finalizable 的类上的方法在方法执行期间保持this 对象处于活动状态。 The this value is treated like a local variable.

例如,thismyFunction 中的 someNativeCall 执行期间保持活动状态:

class MyFinalizable implements Finalizable {
  final Pointer nativeResource;

  MyFinalizable(this.nativeResource);

  void myFunction() {
    someNativeCall(nativeResource);
  }
}

void someNativeCall(Pointer nativeResource) {
  // ..
}

在实现 Finalizable 的类上实现涉及可终结性的逻辑作为方法是一种很好的做法。

如果在声明变量的块作用域内创建了闭包,并且该闭包包含对该变量的任何引用,则只要闭包对象存在,或者只要此类闭包的主体正在执行,该变量就会保持活动状态。

例如,finalizable 由闭包对象保持活动状态,直到闭包主体结束:

void doSomething() {
  final resourceAction = myFunction();
  resourceAction(); // `finalizable` is alive until this call returns.
}

void Function() myFunction() {
  final finalizable = MyFinalizable(Pointer.fromAddress(0));
  return () {
    someNativeCall(finalizable.nativeResource);
  };
}

void someNativeCall(Pointer nativeResource) {
  // ..
}

class MyFinalizable implements Finalizable {
  final Pointer nativeResource;

  MyFinalizable(this.nativeResource);
}

只有捕获的变量才能通过闭包保持活动状态,而不是所有变量。

例如,finalizable 不会被返回的闭包对象保持活动状态:

void Function() myFunction() {
  final finalizable = MyFinalizable(Pointer.fromAddress(0));
  final nativeResource = finalizable.nativeResource;
  return () {
    someNativeCall(nativeResource);
  };
}

void someNativeCall(Pointer nativeResource) {
  // ..
}

class MyFinalizable implements Finalizable {
  final Pointer nativeResource;

  MyFinalizable(this.nativeResource);
}

如果从可终结对象中提取的资源超出了它所取自的可终结变量的范围,则很可能是一个错误。

Finalizable 变量的行为也适用于异步函数。只要任何代码仍然可以在声明变量的范围内执行,或者在捕获变量的闭包中执行,这些变量就会保持活动状态,即使在执行期间存在异步延迟。

例如,finalizableawait someAsyncCall() 期间保持活动状态:

Future<void> myFunction() async {
  final finalizable = MyFinalizable();
  await someAsyncCall();
}

Future<void> someAsyncCall() async {
  // ..
}

class MyFinalizable implements Finalizable {
  // ..
}

同样在异步代码中,如果从可终结对象中提取的资源超出了它所取自的可终结变量的范围,则可能会出现错误。如果您必须从 Finalizable 中提取资源,则应通过 await 使用任何使用该资源的异步代码来确保定义 Finalizable 的范围比资源更长。

例如,this 一直保持活动状态,直到 resource 不再在 useAsync1 中使用,但在 useAsync2useAsync3 中不再使用:

class MyFinalizable {
  final Pointer<Int8> resource;

  MyFinalizable(this.resource);

  Future<int> useAsync1() async {
    return await useResource(resource);
  }

  Future<int> useAsync2() async {
    return useResource(resource);
  }

  Future<int> useAsync3() {
    return useResource(resource);
  }
}

/// Does not use [resource] after the returned future completes.
Future<int> useResource(Pointer<Int8> resource) async {
  return resource.value;
}

It is possible for an asynchronous function to stall at an await, such that the runtime system can see that there is no possible way for that await to complete. In that case, no code after the await will ever execute, including finally blocks, and the variable may be considered dead along with everything else.

如果您自己不打算让变量保持活动状态,请确保将可终结对象传递给其他函数,而不仅仅是其资源。

例如,finalizable 在运行到其作用域的末尾后不会被 myFunction 保持活动状态,而 someAsyncCall 仍然可以继续执行。但是,finalizablesomeAsyncCall 本身保持活动状态:

void myFunction() {
  final finalizable = MyFinalizable();
  someAsyncCall(finalizable);
}

Future<void> someAsyncCall(MyFinalizable finalizable) async {
  // ..
}

class MyFinalizable implements Finalizable {
  // ..
}

相关用法


注:本文由纯净天空筛选整理自dart.dev大神的英文原创作品 Finalizable class。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。