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
对象)。
考虑将 register
和 fromString
更改为:
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());
}
我的代码在 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
对象)。
考虑将 register
和 fromString
更改为:
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());
}