【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文) (4)

最后使用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())"'; } } } find

find方法还是蛮简单的,就是从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里面写了回收实例的操作

淦!

内置回收机制

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyyyj.html