Committed by
GitHub
Merge pull request #589 from roipeker/fix_get_create
Fix for Get.create() lifecycle
Showing
3 changed files
with
52 additions
and
4 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,14 +187,18 @@ class GetInstance { | @@ -159,14 +187,18 @@ 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); |
167 | - _singl[key].isInit = true; | ||
168 | - if (GetConfig.smartManagement != SmartManagement.onlyBuilder) { | ||
169 | - _registerRouteInstance<S>(tag: name); | 197 | + if (_singl[key].isSingleton) { |
198 | + _singl[key].isInit = true; | ||
199 | + if (GetConfig.smartManagement != SmartManagement.onlyBuilder) { | ||
200 | + _registerRouteInstance<S>(tag: name); | ||
201 | + } | ||
170 | } | 202 | } |
171 | } | 203 | } |
172 | return true; | 204 | return true; |
@@ -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