NoSuchMethodEror:试图调用非函数,例如 null:

NoSuchMethodEror: tried to call a non-function, such as null:

我的代码在 android 模拟器上运行良好,但在网络上出错。

import 'package:parivaar/components/screens/home/Home.dart';

typedef T Constructor<T>();

final Map<String, Constructor<Object>> _constructors =
    <String, Constructor<Object>>{};

void register<T>(Constructor<T> constructor) {
  _constructors[T.toString()] = constructor;
}

class ClassBuilder {
  static void registerClasses() {
    register<Home>(() => Home());
  }

  static dynamic fromString(String type) {
    return _constructors[type]();
  }
}

我按如下方式调用该函数:

class _MyHomePageState 扩展状态 { KFDrawerController _drawerController;

  @override
  void initState() {
    super.initState();
    _drawerController = KFDrawerController(
      initialPage: ClassBuilder.fromString('Home'),
.
..
...
....

您可能假设 T.toString() returns 类型的源名称为字符串。从来没有人承诺过。 它适用于本机,但在网络上,您通常会针对 size 进行优化,并且“缩小”会将所有长名称转换为较短的名称。这样,类型 Home 的名称不再是字符串 "Home".

我通常不推荐取决于类型的字符串表示(或 Type 对象)。

考虑将 registerfromString 更改为:

void register<T>(Constructor<T> constructor) {
  _constructors[T] = constructor;
}

  static T fromType<T>() => _constructors[T]();

这依赖于 Type 对象相等性,这是一个定义明确的操作。 不完美,但仍然比通过字符串更好。

如果您需要从 字符串 动态创建您不知道类型的对象,那么我会要求您在注册时提供密钥字符串,将 register 更改为:

void register<T>(String key, Constructor<T> constructor) {
  _constructors[key] = constructor;
}

注册类型如下:

static void registerClasses() {
  register<Home>("Home", () => Home());
}