0

我编写了一个 Swift/IOS 包来外部化和标准化我所有的 Social/Federated/Firebase 身份验证样板(SDK 和 UI)。我已经把它移植到 Flutter 作为一个学习练习......但也允许通过 config.in 传入自定义 UI。

由于我是 Flutter 和 Riverpod 的新手,恐怕我会犯一些严重的错误,并且希望在我深入之前得到各位专家的反馈。

该软件包称为“社交登录助手”或 SLH,这是我想要的公共 API:

  runApp(
    slh.authStateBuilder(
      builder: (authStatus) {
        switch (authStatus.stage) {
          case SlhResultStage.initializing:
            return SplashScreen();
          case SlhResultStage.unauthenticated:
            // using Riverpod and Nav 2.0
            return slh.authFlowUi;
          case SlhResultStage.authenticated:
            return ExampleApp(appKey, authStatus, slh.logoutCallback);
          case SlhResultStage.wantsAnnonOnlyFeatures:
            return ExampleApp(appKey, null, slh.startAuthCallback);
          case SlhResultStage.excessiveFailures:  // restart the app
            return TotalFailure();
        }
      },
    ),
  );

从上面可以看出,根目录下的 State/Stream 构建器绝不能被垃圾收集或清除。我不清楚 Riverpod 是否以及何时处置我的提供者,或者 Dart 本身是否会收集必须保持不朽的对象。我也不确定是使用 StreamProvider 还是 State 提供者?

正如你在下面看到的,我故意制造了一个内存泄漏(死锁)来保护我。我确定这是一种反模式,但作为新手,我不确定如何保证不朽。

欢迎所有指导和明确的反馈。

class LivingAuthState extends StateNotifier<SlhResultStage> {
  // create deadly embrace to prevent this from ever being collected
  _Unpurgeable _up;
  LivingAuthState() : super(SlhResultStage.initializing) {
    //
    final StreamProvider<SlhResultStage> rssp =
        StreamProvider<SlhResultStage>((ref) {
      return this.stream.asBroadcastStream();
    });

    _up = _Unpurgeable(this, rssp);

    // how do I keep rssp from ever being collected??
  }
  StreamProvider<SlhResultStage> get authStatusStream => _up.rssp;

  void logout() {
    this.state = SlhResultStage.unauthenticated;
  }

  void restartLogin() {
    this.state = SlhResultStage.unauthenticated;
  }
}

class _Unpurgeable {
  final LivingAuthState _aliveState;
  final StreamProvider<SlhResultStage> rssp;
  _Unpurgeable(this._aliveState, this.rssp);
}

我希望在 Riverpod 文档中看到的一项改进是,在没有主动侦听器的情况下,提供者在自我处置/垃圾收集之前能够存活多久。

啊,看起来我可以继承 AlwaysAliveProviderBase() 以实现相同的目标......我会对此进行试验。

4

1 回答 1

1

将您的提供者 final 移至顶层。Riverpod 提供者是顶级的最终变量。

还要记住将您的应用程序包装在riverpod 提供程序中。

于 2020-11-14T22:00:29.490 回答