Committed by
GitHub
Merge pull request #589 from roipeker/fix_get_create
Fix for Get.create() lifecycle
Showing
3 changed files
with
49 additions
and
1 deletions
| @@ -74,3 +74,9 @@ captures/ | @@ -74,3 +74,9 @@ captures/ | ||
| 74 | !.vscode/tasks.json | 74 | !.vscode/tasks.json |
| 75 | !.vscode/launch.json | 75 | !.vscode/launch.json |
| 76 | !.vscode/extensions.json | 76 | !.vscode/extensions.json |
| 77 | + | ||
| 78 | +example/macos/Flutter/ephemeral/Flutter-Generated.xcconfig | ||
| 79 | + | ||
| 80 | +example/macos/Flutter/ephemeral/ | ||
| 81 | + | ||
| 82 | +example/macos/Flutter/GeneratedPluginRegistrant.swift |
| @@ -38,9 +38,15 @@ extension Inst on GetInterface { | @@ -38,9 +38,15 @@ extension Inst on GetInterface { | ||
| 38 | {String tag, bool permanent = false}) async => | 38 | {String tag, bool permanent = false}) async => |
| 39 | GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent); | 39 | GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent); |
| 40 | 40 | ||
| 41 | - /// Creates a new Instance<[S]> from the <[S]>[builder] callback. | 41 | + /// Creates a new Class Instance [S] from the builder callback[S]. |
| 42 | /// Every time [find]<[S]>() is used, it calls the builder method to generate | 42 | /// Every time [find]<[S]>() is used, it calls the builder method to generate |
| 43 | /// a new Instance [S]. | 43 | /// a new Instance [S]. |
| 44 | + /// It also registers each [instance.onClose()] with the current | ||
| 45 | + /// Route [GetConfig.currentRoute] to keep the lifecycle active. | ||
| 46 | + /// Is important to know that the instances created are only stored per Route. | ||
| 47 | + /// So, if you call `Get.delete<T>()` the "instance factory" used in this | ||
| 48 | + /// method ([Get.create<T>()]) will be removed, but NOT the instances | ||
| 49 | + /// already created by it. | ||
| 44 | /// | 50 | /// |
| 45 | /// Example: | 51 | /// Example: |
| 46 | /// | 52 | /// |
| 1 | +import 'dart:async'; | ||
| 2 | +import 'dart:collection'; | ||
| 3 | + | ||
| 1 | import '../core/log.dart'; | 4 | import '../core/log.dart'; |
| 2 | import '../navigation/root/smart_management.dart'; | 5 | import '../navigation/root/smart_management.dart'; |
| 3 | import '../state_manager/rx/rx_core/rx_interface.dart'; | 6 | import '../state_manager/rx/rx_core/rx_interface.dart'; |
| @@ -30,6 +33,12 @@ class GetInstance { | @@ -30,6 +33,12 @@ class GetInstance { | ||
| 30 | /// created to manage the memory. | 33 | /// created to manage the memory. |
| 31 | static final Map<String, String> _routesKey = {}; | 34 | static final Map<String, String> _routesKey = {}; |
| 32 | 35 | ||
| 36 | + /// Stores the onClose() references of instances created with [Get.create()] | ||
| 37 | + /// using the [GetConfig.currentRoute]. | ||
| 38 | + /// Experimental feature to keep the lifecycle and memory management with | ||
| 39 | + /// non-singleton instances. | ||
| 40 | + static final Map<String, HashSet<Function>> _routesByCreate = {}; | ||
| 41 | + | ||
| 33 | static final _queue = GetQueue(); | 42 | static final _queue = GetQueue(); |
| 34 | 43 | ||
| 35 | /// Creates a new Instance<S> lazily from the [<S>builder()] callback. | 44 | /// Creates a new Instance<S> lazily from the [<S>builder()] callback. |
| @@ -101,6 +110,12 @@ class GetInstance { | @@ -101,6 +110,12 @@ class GetInstance { | ||
| 101 | /// Creates a new Class Instance [S] from the builder callback[S]. | 110 | /// Creates a new Class Instance [S] from the builder callback[S]. |
| 102 | /// Every time [find]<[S]>() is used, it calls the builder method to generate | 111 | /// Every time [find]<[S]>() is used, it calls the builder method to generate |
| 103 | /// a new Instance [S]. | 112 | /// a new Instance [S]. |
| 113 | + /// It also registers each [instance.onClose()] with the current | ||
| 114 | + /// Route [GetConfig.currentRoute] to keep the lifecycle active. | ||
| 115 | + /// Is important to know that the instances created are only stored per Route. | ||
| 116 | + /// So, if you call `Get.delete<T>()` the "instance factory" used in this | ||
| 117 | + /// method ([Get.create<T>()]) will be removed, but NOT the instances | ||
| 118 | + /// already created by it. | ||
| 104 | /// | 119 | /// |
| 105 | /// Example: | 120 | /// Example: |
| 106 | /// | 121 | /// |
| @@ -144,6 +159,19 @@ class GetInstance { | @@ -144,6 +159,19 @@ class GetInstance { | ||
| 144 | } | 159 | } |
| 145 | }); | 160 | }); |
| 146 | 161 | ||
| 162 | + /// Removes [Get.create()] instances registered in [routeName]. | ||
| 163 | + if (_routesByCreate.containsKey(routeName)) { | ||
| 164 | + for (final onClose in _routesByCreate[routeName]) { | ||
| 165 | + // assure the [DisposableInterface] instance holding a reference | ||
| 166 | + // to [onClose()] wasn't disposed. | ||
| 167 | + if (onClose != null) { | ||
| 168 | + await onClose(); | ||
| 169 | + } | ||
| 170 | + } | ||
| 171 | + _routesByCreate[routeName].clear(); | ||
| 172 | + _routesByCreate.remove(routeName); | ||
| 173 | + } | ||
| 174 | + | ||
| 147 | for (final element in keysToRemove) { | 175 | for (final element in keysToRemove) { |
| 148 | await delete(key: element); | 176 | await delete(key: element); |
| 149 | } | 177 | } |
| @@ -159,16 +187,20 @@ class GetInstance { | @@ -159,16 +187,20 @@ class GetInstance { | ||
| 159 | /// Optionally associating the current Route to the lifetime of the instance, | 187 | /// Optionally associating the current Route to the lifetime of the instance, |
| 160 | /// if [GetConfig.smartManagement] is marked as [SmartManagement.full] or | 188 | /// if [GetConfig.smartManagement] is marked as [SmartManagement.full] or |
| 161 | /// [GetConfig.keepFactory] | 189 | /// [GetConfig.keepFactory] |
| 190 | + /// Only flags `isInit` if it's using `Get.create()` | ||
| 191 | + /// (not for Singletons access). | ||
| 162 | bool _initDependencies<S>({String name}) { | 192 | bool _initDependencies<S>({String name}) { |
| 163 | final key = _getKey(S, name); | 193 | final key = _getKey(S, name); |
| 164 | final isInit = _singl[key].isInit; | 194 | final isInit = _singl[key].isInit; |
| 165 | if (!isInit) { | 195 | if (!isInit) { |
| 166 | _startController<S>(tag: name); | 196 | _startController<S>(tag: name); |
| 197 | + if (_singl[key].isSingleton) { | ||
| 167 | _singl[key].isInit = true; | 198 | _singl[key].isInit = true; |
| 168 | if (GetConfig.smartManagement != SmartManagement.onlyBuilder) { | 199 | if (GetConfig.smartManagement != SmartManagement.onlyBuilder) { |
| 169 | _registerRouteInstance<S>(tag: name); | 200 | _registerRouteInstance<S>(tag: name); |
| 170 | } | 201 | } |
| 171 | } | 202 | } |
| 203 | + } | ||
| 172 | return true; | 204 | return true; |
| 173 | } | 205 | } |
| 174 | 206 | ||
| @@ -193,6 +225,10 @@ class GetInstance { | @@ -193,6 +225,10 @@ class GetInstance { | ||
| 193 | i.onStart(); | 225 | i.onStart(); |
| 194 | GetConfig.log('"$key" has been initialized'); | 226 | GetConfig.log('"$key" has been initialized'); |
| 195 | } | 227 | } |
| 228 | + if (!_singl[key].isSingleton && i.onClose != null) { | ||
| 229 | + _routesByCreate[GetConfig.currentRoute] ??= HashSet<Function>(); | ||
| 230 | + _routesByCreate[GetConfig.currentRoute].add(i.onClose); | ||
| 231 | + } | ||
| 196 | } | 232 | } |
| 197 | } | 233 | } |
| 198 | 234 |
-
Please register or login to post a comment