最后使用find方法,返回传入的实例
class GetInstance { factory GetInstance() => _getInstance ??= GetInstance._(); const GetInstance._(); static GetInstance? _getInstance; static final Map<String, _InstanceBuilderFactory> _singl = {}; S put<S>( S dependency, { String? tag, bool permanent = false, @deprecated InstanceBuilderCallback<S>? builder, }) { _insert( isSingleton: true, name: tag, permanent: permanent, builder: builder ?? (() => dependency)); return find<S>(tag: tag); } void _insert<S>({ bool? isSingleton, String? name, bool permanent = false, required InstanceBuilderCallback<S> builder, bool fenix = false, }) { final key = _getKey(S, name); _singl.putIfAbsent( key, () => _InstanceBuilderFactory<S>( isSingleton, builder, permanent, false, fenix, name, ), ); } String _getKey(Type type, String? name) { return name == null ? type.toString() : type.toString() + name; } S find<S>({String? tag}) { final key = _getKey(S, tag); if (isRegistered<S>(tag: tag)) { if (_singl[key] == null) { if (tag == null) { throw 'Class "$S" is not registered'; } else { throw 'Class "$S" with tag "$tag" is not registered'; } } final i = _initDependencies<S>(name: tag); return i ?? _singl[key]!.getDependency() as S; } else { // ignore: lines_longer_than_80_chars throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"'; } } } findfind方法还是蛮简单的,就是从map中取数据的操作
S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);看下具体逻辑
先判断 _singl 中是否含有该key的数据,有则取,无则抛异常
关键代码: _singl[key]!.getDependency() as S ,直接通过key去map取值就行了
class GetInstance { factory GetInstance() => _getInstance ??= GetInstance._(); const GetInstance._(); static GetInstance? _getInstance; static final Map<String, _InstanceBuilderFactory> _singl = {}; String _getKey(Type type, String? name) { return name == null ? type.toString() : type.toString() + name; } bool isRegistered<S>({String? tag}) => _singl.containsKey(_getKey(S, tag)); S find<S>({String? tag}) { final key = _getKey(S, tag); if (isRegistered<S>(tag: tag)) { if (_singl[key] == null) { if (tag == null) { throw 'Class "$S" is not registered'; } else { throw 'Class "$S" with tag "$tag" is not registered'; } } final i = _initDependencies<S>(name: tag); return i ?? _singl[key]!.getDependency() as S; } else { // ignore: lines_longer_than_80_chars throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"'; } } } GetBuilder刷新机制 使用为了知识的连续性,此处简单的写下使用
逻辑层
class GetCounterEasyLogic extends GetxController { var count = 0; void increase() { ++count; update(); } }界面
class GetCounterEasyPage extends StatelessWidget { final GetCounterEasyLogic logic = Get.put(GetCounterEasyLogic()); @override Widget build(BuildContext context) { return BaseScaffold( appBar: AppBar(title: const Text('计数器-简单式')), body: Center( child: GetBuilder<GetCounterEasyLogic>(builder: (logic) { return Text( '点击了 ${logic.count} 次', style: TextStyle(fontSize: 30.0), ); }), ), floatingActionButton: FloatingActionButton( onPressed: () => logic.increase(), child: Icon(Icons.add), ), ); } } GetBuilder有一天,我躺在床上思考
Obx的状态管理,GetXController实例回收是放在路由里面,在很多场景下,存在一些局限性
后来我想到,GetBuilder使用带泛型,这就能拿到GetxController实例,GetBuilder又是StatefulWidget
这样就可以使用它来回收实例,能解决很多场景下,GetXController实例无法回收的问题(不使用Getx路由)
我兴致冲冲的打开Getx项目,准备提PR,然后发现GetBuilder已经在dispose里面写了回收实例的操作
淦!
内置回收机制