戰(zhàn)指南:Get.put / Get.lazyPut / Get.create 與 Bindings 智能生命周期的完整解析)
前端【免費(fèi)下載鏈接】getxOpen screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.項(xiàng)目地址https://gitcode.com/gh_mirrors/ge/getx點(diǎn)擊查看免費(fèi)下載本篇技術(shù)指南圍繞 GetGetX的依賴管理系統(tǒng)展開詳細(xì)講解Get.put、Get.lazyPut、Get.putAsync、Get.create四種實(shí)例化方法的參數(shù)與適用場(chǎng)景以及Get.find、Get.delete、replace/lazyReplace的使用方式并結(jié)合源碼剖析 Bindings、BindingsBuilder 與 SmartManagement 的底層實(shí)現(xiàn)。讀完本文你將能夠在不依賴 Provider context 與 InheritedWidget 的情況下完成依賴注入理解permanent與fenix的本質(zhì)區(qū)別并為路由配置自動(dòng)回收、按需重建的控制器生命周期。本文對(duì)應(yīng)的原始文檔位于 documentation/ar_EG/dependency_management.md英文原版見 documentation/en_US/dependency_management.md全部源碼佐證均來(lái)自當(dāng)前倉(cāng)庫(kù) lib/get_instance 與 lib/get_state_manager 等目錄。一、為什么需要 Get 的依賴管理器Get 提供了一套簡(jiǎn)單而強(qiáng)大的依賴管理器你不需要 Provider 的context不需要InheritedWidget只需要一行代碼就能像獲取普通類一樣拿到你的 Controller 或 Bloc 實(shí)例Controller controller Get.put(Controller()); // 代替 Controller controller Controller();其核心思想是不要在你使用類的內(nèi)部去實(shí)例化它而是把它實(shí)例化到 Get 這個(gè)全局容器里讓它在整個(gè) App 范圍內(nèi)可用。之后你可以像使用普通類一樣使用這個(gè) controller或 Bloc 類。使用前有兩個(gè)重要提示文檔原文 Note如果你正在使用 Get 的狀態(tài)管理器請(qǐng)重點(diǎn)關(guān)注 Bindings API它能更輕松地將視圖與控制器連接起來(lái)Get 的依賴管理與其他部分狀態(tài)管理、路由是解耦的。即便你的應(yīng)用已經(jīng)在使用其他任何狀態(tài)管理器也無(wú)需更換可以直接無(wú)沖突地使用這套依賴注入管理器。從源碼看這套機(jī)制的核心是一個(gè)以類型和可選的 tag為 key 的 HashMap。在 extension_instance.dart 中_singl保存了所有通過(guò)Get.put注冊(cè)的實(shí)例工廠_getKey生成 key 的邏輯是name null ? type.toString() : type.toString() name即類型名 tag共同決定唯一性這正是同一類型可通過(guò) tag 注冊(cè)多個(gè)實(shí)例的原理。二、四大實(shí)例化方法Instancing Methods文檔將注冊(cè)依賴的方式歸納為四種方法各有各的參數(shù)與適用場(chǎng)景。Get.put()最常用的同步注冊(cè)Get.put是最常見的插入依賴的方式例如視圖對(duì)應(yīng)的 ControllerGet.putSomeClass(SomeClass()); Get.putLoginController(LoginController(), permanent: true); Get.putListItemController(ListItemController, tag: some unique string);Get.put支持的全部參數(shù)如下來(lái)自文檔Get.putS( // 必填想要保存的類實(shí)例比如 controller 或任何對(duì)象 // 注意S 表示它可以是任意類型的類 S dependency // 可選當(dāng)你需要多個(gè)同類型實(shí)例時(shí)使用 // 因?yàn)橥ǔS?Get.findController() 獲取類需要用 tag 告訴 Get 你要哪個(gè)實(shí)例 // 必須是唯一的字符串 String tag, // 可選默認(rèn)情況下Get 會(huì)在實(shí)例不再被使用時(shí)將其釋放 // 例如被關(guān)閉的視圖的 controller。但如果這個(gè)實(shí)例需要在整個(gè) App // 中一直存活比如 SharedPreferences 之類的實(shí)例就使用這個(gè)參數(shù) // 默認(rèn)為 false bool permanent false, // 可選允許你在測(cè)試中先使用抽象類再將其替換為另一個(gè)類并繼續(xù)測(cè)試 // 默認(rèn)為 false bool overrideAbstract false, // 可選允許你用一個(gè)函數(shù)來(lái)創(chuàng)建依賴而不是直接傳依賴本身 // 這個(gè)參數(shù)不常用 InstanceBuilderCallbackS builder, )結(jié)合源碼可以更精確地理解put的行為。在 extension_instance.dart 中S putS( S dependency, { String? tag, bool permanent false, }) { _insert( isSingleton: true, name: tag, permanent: permanent, builder: (() dependency)); return findS(tag: tag); }它通過(guò)內(nèi)部方法_insert以isSingleton: true、permanent: permanent的方式把實(shí)例登記進(jìn)_singl隨后立即調(diào)用findS也就是說(shuō)put是注冊(cè)即初始化實(shí)例在調(diào)用返回時(shí)已經(jīng)可用。_insert中還有一個(gè)細(xì)節(jié)如果該 key 已存在且不是isDirty狀態(tài)會(huì)直接返回避免重復(fù)注冊(cè)覆蓋。倉(cāng)庫(kù)測(cè)試 get_instance_test.dart 驗(yàn)證了Get.put后Get.find返回同一實(shí)例。Get.lazyPut()懶加載lazyPut允許你懶加載依賴只有第一次真正使用Get.find時(shí)才會(huì)實(shí)例化。這非常適合計(jì)算開銷大的類或者像 Bindings 類里集中注冊(cè)多個(gè)類、但當(dāng)時(shí)并不需要全部使用的情況。/// ApiMock 只有在有人第一次使用 Get.findApiMock 時(shí)才會(huì)被調(diào)用 Get.lazyPutApiMock(() ApiMock()); Get.lazyPutFirebaseAuth( () { // ... 如果需要可以在這里寫一些邏輯 return FirebaseAuth(); }, tag: Math.random().toString(), fenix: true ) Get.lazyPutController( () Controller() )lazyPut的參數(shù)說(shuō)明來(lái)自文檔Get.lazyPutS( // 必填一個(gè)方法在類第一次被調(diào)用時(shí)執(zhí)行 InstanceBuilderCallback builder, // 可選與 Get.put() 相同用于需要同一類的多個(gè)不同實(shí)例 // 必須是唯一的 String tag, // 可選與 permanent 類似區(qū)別在于實(shí)例在不再使用時(shí)會(huì)被丟棄 // 但當(dāng)再次需要它時(shí)Get 會(huì)重新創(chuàng)建實(shí)例 // 與 bindings API 中的 SmartManagement.keepFactory 行為一致 // 默認(rèn)為 false bool fenix false )源碼層面lazyPut與put一樣調(diào)用_insert但不會(huì)立即執(zhí)行find實(shí)例只是以工廠回調(diào)的形式注冊(cè)同時(shí)有個(gè)值得注意的默認(rèn)邏輯fenix: fenix ?? Get.smartManagement SmartManagement.keepFactory,也就是說(shuō)如果你沒有顯式傳fenix那么fenix的值會(huì)跟隨全局smartManagement配置當(dāng)SmartManagement.keepFactory生效時(shí)lazyPut默認(rèn)開啟 fenix 行為詳見后文 SmartManagement 章節(jié)。倉(cāng)庫(kù)測(cè)試 get_instance_test.dart 驗(yàn)證了 fenix 語(yǔ)義lazyPut(fenix: true)注冊(cè)的實(shí)例在Get.delete后再find會(huì)重新得到 count 歸零的新實(shí)例而fenix: false時(shí)delete之后find會(huì)直接拋出異常因?yàn)閷?shí)例已從內(nèi)存移除。Get.putAsync()異步注冊(cè)當(dāng)需要注冊(cè)一個(gè)異步創(chuàng)建的實(shí)例時(shí)比如需要await初始化使用Get.putAsyncGet.putAsyncSharedPreferences(() async { final prefs await SharedPreferences.getInstance(); await prefs.setInt(counter, 12345); return prefs; }); Get.putAsyncYourAsyncClass( () async await YourAsyncClass() )參數(shù)說(shuō)明來(lái)自文檔Get.putAsyncS( // 必填一個(gè)異步方法用于實(shí)例化你的類 AsyncInstanceBuilderCallbackS builder, // 可選與 Get.put() 相同用于同一類的多個(gè)不同實(shí)例 // 必須是唯一的 String tag, // 可選與 Get.put() 相同用于需要在整個(gè) App 中保持存活的實(shí)例 // 默認(rèn)為 false bool permanent false )與Get.put一樣putAsync也是注冊(cè)即初始化區(qū)別僅在于初始化過(guò)程是異步完成的注冊(cè)完成后同樣立即對(duì)實(shí)例調(diào)用find完成初始化。Get.create()每次 find 都重新制造Get.create是最特別的一個(gè)方法文檔原話This one is tricky建議先閱讀方法之間的差異一節(jié)再回來(lái)理解。Get.CreateSomeClass(() SomeClass()); Get.CreateLoginController(() LoginController());參數(shù)說(shuō)明來(lái)自文檔Get.createS( // 必填一個(gè)返回類的函數(shù)每次調(diào)用 Get.find() 時(shí)都會(huì)用這個(gè)函數(shù)重新制造一個(gè)實(shí)例 // 示例Get.createYourClass(() YourClass()) FcBuilderFuncS builder, // 可選與 Get.put() 中的 tag 類似用于同一類的多個(gè)實(shí)例 // 當(dāng)你有一個(gè)列表、每個(gè)列表項(xiàng)都需要自己的 controller 時(shí)非常有用 // 必須是唯一的字符串注意參數(shù)名是 name 而不是 tag String name, // 可選與 Get.put() 中的 permanent 類似用于需要在整個(gè) App 中 // 保持存活的實(shí)例。區(qū)別在于Get.create 中 permanent 默認(rèn)為 true bool permanent true )從當(dāng)前倉(cāng)庫(kù)源碼結(jié)構(gòu)看Get.create的底層語(yǔ)義與內(nèi)部方法spawn一致以isSingleton: false、permanent: true注冊(cè)工廠于是每次Get.find都會(huì)調(diào)用 builder 生成全新實(shí)例非單例同時(shí)因?yàn)閜ermanent: true實(shí)例不會(huì)在頁(yè)面切換時(shí)被回收。文檔特別強(qiáng)調(diào)Get.create的目標(biāo)是創(chuàng)建不共享、但不會(huì)被釋放的實(shí)例例如 listView 中每個(gè)列表項(xiàng)想要獨(dú)立且唯一的 controller因此Get.create必須與 GetWidget 配合使用。倉(cāng)庫(kù)中 get_view.dart 的注釋也印證了這一點(diǎn)Get 會(huì)幫你緩存 controller因此可以安全地使用Get.create。測(cè)試 get_instance_test.dart 驗(yàn)證了該語(yǔ)義連續(xù)兩次find得到的實(shí)例ct1 ct2為false。三、使用已注冊(cè)的實(shí)例Get.find 與 Get.delete想象你已經(jīng)導(dǎo)航了無(wú)數(shù)個(gè)路由現(xiàn)在需要之前遺留在某個(gè) controller 里的數(shù)據(jù)。傳統(tǒng)方案需要狀態(tài)管理器配合 Provider 或 get_it而 Get 只需要一行Get.find不需要任何額外依賴final controller Get.findController(); // 或者 Controller controller Get.find();是的看起來(lái)像魔法Get 會(huì)找到你的 controller 并把它交給你。哪怕你實(shí)例化了 100 萬(wàn)個(gè) controllerGet 也總能給你正確的那個(gè)。拿到實(shí)例后就能正?;謴?fù)數(shù)據(jù)Text(controller.textFromApi);由于返回值就是普通類你可以對(duì)它做任何事int count Get.findSharedPreferences().getInt(counter); print(count); // out: 12345移除一個(gè)實(shí)例Get.deleteController(); // 通常你不需要這樣做因?yàn)?GetX 會(huì)自動(dòng)刪除不再使用的 controller從源碼看find首先檢查該 key 是否已注冊(cè)未注冊(cè)則拋出提示會(huì)提示你調(diào)用Get.put或Get.lazyPut已注冊(cè)則進(jìn)入_initDependencies初始化流程——如果實(shí)例實(shí)現(xiàn)了GetLifeCycleMixin_startController會(huì)觸發(fā)其生命周期方法onStart()并依據(jù)smartManagement配置決定是否把該依賴與當(dāng)前路由綁定RouterReportManager.reportDependencyLinkedToRoute這正是路由移除時(shí)自動(dòng)回收依賴的機(jī)制來(lái)源。此外還有幾個(gè)實(shí)用的配套 APIGet.findOrNullT()已注冊(cè)則返回實(shí)例否則返回null不會(huì)拋異常見 extension_instance.dartGet.isRegisteredT({tag})判斷實(shí)例是否已注冊(cè)extension_instance.dartGet.isPreparedT({tag})判斷是否還有未被初始化的懶加載工廠extension_instance.dartGet.reset()/Get.resetInstance()清空所有注冊(cè)實(shí)例包括永久實(shí)例適合在單元測(cè)試的tearDown中使用見 extension_instance.dart。四、指定替代實(shí)例replace 與 lazyReplace已注冊(cè)的實(shí)例可以被替換為同類或擴(kuò)展類的實(shí)例之后仍可通過(guò)原類型獲取。這就是replace與lazyReplace的用途abstract class BaseClass {} class ParentClass extends BaseClass {} class ChildClass extends ParentClass { bool isChild true; } Get.putBaseClass(ParentClass()); Get.replaceBaseClass(ChildClass()); final instance Get.findBaseClass(); print(instance is ChildClass); // true class OtherClass extends BaseClass {} Get.lazyReplaceBaseClass(() OtherClass()); final instance Get.findBaseClass(); print(instance is ChildClass); // false print(instance is OtherClass); // true源碼實(shí)現(xiàn)印證了替換 刪除 重新注冊(cè)replace先讀取原實(shí)例的permanent狀態(tài)用delete(force: permanent)刪除原實(shí)例再以相同permanent值put新實(shí)例lazyReplace先刪除再以lazyPut注冊(cè)新工廠且fenix未顯式傳入時(shí)默認(rèn)取原實(shí)例的permanent值。這一能力與Get.put的overrideAbstract參數(shù)搭配常用于測(cè)試場(chǎng)景先用抽象類注冊(cè)再替換為具體實(shí)現(xiàn)類。倉(cāng)庫(kù)測(cè)試 get_instance_test.dart 展示了抽象類Service分別通過(guò)lazyPut與spawncreate 語(yǔ)義注入Api實(shí)現(xiàn)的用法。五、permanent 與 fenix方法間的本質(zhì)差異先厘清 permanent 與 fenix二者的根本區(qū)別在于你希望如何存儲(chǔ)實(shí)例。先重申默認(rèn)行為GetX 默認(rèn)會(huì)在實(shí)例不再被使用時(shí)將其刪除。例如屏幕 1 有 controller 1屏幕 2 有 controller 2當(dāng)你用Get.off()或Get.offNamed()把第一條路由移出棧時(shí)controller 1 失去用途隨即被清除。使用permanent: truecontroller 不會(huì)在這次切換中丟失——非常適合希望在整個(gè)應(yīng)用生命周期中存活的 Service。fenix: true用于不擔(dān)心它在頁(yè)面切換時(shí)丟失但當(dāng)你需要它時(shí)它必須是活的的服務(wù)。它會(huì)釋放不再使用的 controller/service/類但當(dāng)你再次需要時(shí)會(huì)從灰燼中重生重新創(chuàng)建一個(gè)新實(shí)例。各方法的底層差異文檔給出了非常清晰的底層機(jī)制對(duì)照結(jié)合 extension_instance.dart 中的_insert實(shí)現(xiàn)可以完全印證方法底層 insert 參數(shù)是否立即 find 初始化實(shí)例形態(tài)典型場(chǎng)景Get.putpermanent: false, isSingleton: true是調(diào)用后立即可用單例直接持有dependency視圖 ControllerGet.putAsyncpermanent: false, isSingleton: true是異步完成后立即 find單例需要 await 初始化的實(shí)例Get.createpermanent: true, isSingleton: false否等界面用到時(shí)才調(diào)用每次 find 新建builderFunc每次執(zhí)行列表項(xiàng)各自的獨(dú)立 Controller需配合 GetWidgetGet.lazyPut不調(diào)用 insert注冊(cè)到工廠區(qū)否首次 find 時(shí)創(chuàng)建首次 find 后成為單例計(jì)算開銷大、集中注冊(cè)但不立即使用的類逐條展開文檔原文要點(diǎn)Get.put 與 Get.putAsync遵循相同的創(chuàng)建順序區(qū)別僅是后者使用異步方法兩者都會(huì)創(chuàng)建并初始化實(shí)例直接通過(guò)內(nèi)部方法insert以permanent: false、isSingleton: true插入內(nèi)存isSingleton參數(shù)唯一的作用是決定取用dependency還是FcBuilderFunc作為依賴來(lái)源。隨后調(diào)用Get.find()立即初始化內(nèi)存中的實(shí)例。Get.create顧名思義會(huì)創(chuàng)建依賴。與put類似也調(diào)用內(nèi)部insert但permanent變?yōu)閠rue、isSingleton變?yōu)閒alse因?yàn)槭莿?chuàng)建不可能是單例。由于permanent: true默認(rèn)享有頁(yè)面切換不丟失的好處同時(shí)Get.find()不會(huì)被立即調(diào)用而是等待界面真正使用它時(shí)才觸發(fā)。值得強(qiáng)調(diào)的是Get.create的設(shè)計(jì)目標(biāo)就是創(chuàng)建不共享、但不會(huì)被釋放的實(shí)例。Get.lazyPut惰性過(guò)程。實(shí)例會(huì)被創(chuàng)建但不會(huì)立即被調(diào)用而是等待使用。與其他方法相反這里不會(huì)調(diào)用insert而是把實(shí)例插入內(nèi)存的另一區(qū)域——負(fù)責(zé)判斷實(shí)例是否可以重建的區(qū)域文檔稱之為factory工廠。這樣未來(lái)要用的東西不會(huì)與正在使用的東西混在一起。fenix的魔法就在這里若fenix: false且smartManagement不是keepFactory那么首次Get.find時(shí)實(shí)例會(huì)從工廠區(qū)移到公共實(shí)例內(nèi)存區(qū)隨即默認(rèn)從工廠區(qū)移除若fenix: true實(shí)例即使在移入公共區(qū)后仍保留在工廠區(qū)將來(lái)可再次被調(diào)用重建。六、Bindings路由、狀態(tài)與依賴的完整集成Bindings 也許是 Get 包最突出的差異化能力之一路由管理器、狀態(tài)管理器與依賴管理器的完整集成。當(dāng)路由從棧中移除時(shí)與之相關(guān)的所有 controller、變量和對(duì)象實(shí)例都會(huì)從內(nèi)存中移除如果你使用了 streams 或 timers它們會(huì)被自動(dòng)關(guān)閉你無(wú)需操心這些。自 Get v2.10 起完整實(shí)現(xiàn)了 Bindings API。你不再需要 init 方法甚至可以不手動(dòng)聲明 controller 的類型——可以在合適的地方啟動(dòng)你的 controller 與 services。Binding 類的作用是把依賴注入解耦同時(shí)把路由與狀態(tài)管理器、依賴管理器綁定在一起這讓 Get 能知道某個(gè) controller 被使用時(shí)正在顯示哪個(gè)界面也知道在哪里、以何種方式釋放它。此外 Binding 類還允許你獲得 SmartManager 配置控制權(quán)決定依賴是在路由移出棧時(shí)、還是使用它的 widget 布局時(shí)被清理或兩者都不清理。Bindings 類創(chuàng)建一個(gè)實(shí)現(xiàn)Binding的類注意當(dāng)前源碼中Bindings已標(biāo)記為廢棄推薦使用Binding見 bindings_interface.dartclass HomeBinding implements Binding {}IDE 會(huì)自動(dòng)提示你重寫dependencies方法在該方法里注冊(cè)這個(gè)路由要用到的所有類class HomeBinding implements Binding { override void dependencies() { Get.lazyPutHomeController(() HomeController()); Get.putService(() Api()); } } class DetailsBinding implements Binding { override void dependencies() { Get.lazyPutDetailsController(() DetailsController()); } }然后在路由聲明中告知 Get 使用該 Binding從而打通路由管理器 ? 依賴 ? 狀態(tài)使用命名路由getPages: [ GetPage( name: /, page: () HomeView(), binding: HomeBinding(), ), GetPage( name: /details, page: () DetailsView(), binding: DetailsBinding(), ), ];使用普通路由Get.to(Home(), binding: HomeBinding()); Get.to(DetailsView(), binding: DetailsBinding())這樣你就不必再擔(dān)心應(yīng)用的內(nèi)存管理Get 會(huì)替你完成。Binding 類會(huì)在路由被調(diào)用時(shí)執(zhí)行同時(shí)你也可以在GetMaterialApp中設(shè)置initialBinding集中注冊(cè)那些一開始就要?jiǎng)?chuàng)建的依賴GetMaterialApp( initialBinding: SampleBind(), home: Home(), );倉(cāng)庫(kù)中initialBinding是GetMaterialApp與GetCupertinoApp的標(biāo)準(zhǔn)配置項(xiàng)見 get_cupertino_app.dart示例工程也采用了 Binding 路由的完整分層可參考 example/lib/routes/app_pages.dart 與 example_nav2/lib/app/routes/app_pages.dart。BindingsBuilder默認(rèn)方式是為每個(gè)路由創(chuàng)建實(shí)現(xiàn)Bindings的類但也可以用BindingsBuilder回調(diào)直接用函數(shù)注冊(cè)任意依賴getPages: [ GetPage( name: /, page: () HomeView(), binding: BindingsBuilder(() { Get.lazyPutControllerX(() ControllerX()); Get.putService(() Api()); }), ), GetPage( name: /details, page: () DetailsView(), binding: BindingsBuilder(() { Get.lazyPutDetailsController(() DetailsController()); }), ), ];這樣就不必為每個(gè)路由單獨(dú)創(chuàng)建一個(gè) Binding 類更簡(jiǎn)潔。文檔說(shuō)明兩種方式都完全有效按個(gè)人偏好選擇即可。七、SmartManagement智能內(nèi)存管理GetX 默認(rèn)會(huì)釋放不再使用的 controller即使發(fā)生異常、使用它的 widget 未被正確銷毀也不例外——這就是依賴管理的full模式。如果你希望改變 GetX 控制類釋放的方式可以通過(guò)SmartManagement類設(shè)置不同行為。源碼中它是一個(gè)三值枚舉定義于 smart_management.dart默認(rèn)值為full見 get_interface.dart。如何修改通常你不需要修改此配置如果確實(shí)需要在GetMaterialApp上指定即可void main () { runApp( GetMaterialApp( smartManagement: SmartManagement.onlyBuilder // 在這里配置 home: Home(), ) ) }smartManagement是GetMaterialApp的內(nèi)置配置參數(shù)默認(rèn)SmartManagement.full見 get_material_app.dart。SmartManagement.full默認(rèn)模式。釋放未被使用且未被標(biāo)記為 permanent的類。絕大多數(shù)情況下你都應(yīng)保持該配置不變?nèi)绻闶?GetX 新手請(qǐng)不要改動(dòng)它。SmartManagement.onlyBuilder該模式下只有通過(guò)init:啟動(dòng)、或通過(guò) Binding 里的Get.lazyPut()加載的 controller 才會(huì)被釋放。如果你使用Get.put()、Get.putAsync()或其他任何方式注冊(cè)SmartManagement 將沒有權(quán)限刪除該依賴。而默認(rèn)行為full下即使是通過(guò)Get.put實(shí)例化的 widget 也會(huì)被移除這與onlyBuilder不同。注意命名當(dāng)前倉(cāng)庫(kù)源碼中的枚舉名為onlyBuilder單數(shù)部分文檔版本寫作onlyBuilders復(fù)數(shù)使用時(shí)以源碼為準(zhǔn)。此外路由側(cè)也有對(duì)應(yīng)邏輯RouterReportManager只有在smartManagement ! SmartManagement.onlyBuilder時(shí)才把依賴與路由綁定見 router_report.dart這解釋了為何onlyBuilder模式下Get.put注冊(cè)的實(shí)例不受路由生命周期管理。SmartManagement.keepFactory與SmartManagement.full一樣在依賴不再使用時(shí)移除它但會(huì)保留其工廠factory意味著當(dāng)你再次需要該實(shí)例時(shí)會(huì)重新創(chuàng)建。因此它和lazyPut(fenix: true)效果等價(jià)——事實(shí)上源碼中l(wèi)azyPut的默認(rèn)fenix正是跟隨smartManagement keepFactory見 extension_instance.dart。八、Bindings 底層工作原理文檔給出了非常直觀的底層說(shuō)明Bindings 創(chuàng)建的是臨時(shí)工廠transitory factories——在你點(diǎn)擊跳轉(zhuǎn)另一界面的瞬間創(chuàng)建并在界面切換動(dòng)畫結(jié)束的瞬間銷毀整個(gè)過(guò)程快到 analyzer 都無(wú)法察覺。當(dāng)你再次導(dǎo)航到該界面時(shí)會(huì)重新調(diào)用一個(gè)新的臨時(shí)工廠。因此 Bindings 方式優(yōu)于直接使用SmartManagement.keepFactory但如果你不想創(chuàng)建 Bindings或想把所有依賴放在同一個(gè) Binding 里keepFactory會(huì)是有效的替代。工廠本身占用內(nèi)存極小——它不持有實(shí)例只保存一個(gè)具有該類形狀的函數(shù)內(nèi)存成本非常低。不過(guò)由于本庫(kù)的設(shè)計(jì)目標(biāo)是用最少的資源獲得最大性能Get 默認(rèn)連工廠也會(huì)移除。二者按需選用即可。九、注意事項(xiàng)與最佳實(shí)踐Notes文檔在結(jié)尾給出了兩條關(guān)鍵提醒結(jié)合倉(cāng)庫(kù)實(shí)現(xiàn)可歸納為以下最佳實(shí)踐不要在使用多個(gè) Bindings 時(shí)使用SmartManagement.keepFactory。它被設(shè)計(jì)用于不使用 Bindings或僅在 GetMaterialApp 的 initialBinding 中關(guān)聯(lián)單個(gè) Binding的場(chǎng)景。Bindings 完全是可選的。你也可以直接在類中使用Get.put()與Get.find()而毫無(wú)問題。但如果你使用 Services 或任何其他抽象建議使用 Bindings 以獲得更好的組織性。GetxService 不可被普通delete刪除。源碼 lifecycle.dart 說(shuō)明與 GetxController 不同GetxService 一旦啟動(dòng)就常駐內(nèi)存例如 Auth 服務(wù)唯一的移除方式是Get.reset()。delete方法對(duì)實(shí)現(xiàn)GetxServiceMixin的實(shí)例也會(huì)直接返回除非force: true測(cè)試 get_instance_test.dart 驗(yàn)證了這一行為普通delete后isRegistered仍為true只有delete(force: true)才會(huì)真正移除。permanent 實(shí)例的刪除需要 force。delete方法對(duì)permanent: true的實(shí)例會(huì)拒絕刪除并輸出錯(cuò)誤日志除非顯式傳入force: true見 extension_instance.dart。在測(cè)試中善用Get.reset()。它會(huì)清空所有注冊(cè)實(shí)例包括永久實(shí)例與路由綁定clearRouteBindings保證測(cè)試之間互不污染見 extension_instance.dart。生命周期鉤子如果你的 Controller 混入GetLifeCycleMixin如 GetxController實(shí)例創(chuàng)建時(shí)會(huì)依次觸發(fā)onStart → onInit → onReady銷毀時(shí)觸發(fā)onDelete → onClose見 lifecycle.dart。這讓你可以在onClose中關(guān)閉 streams、timers、TextEditingController 等資源配合路由回收機(jī)制實(shí)現(xiàn)無(wú)泄漏的內(nèi)存管理。以上內(nèi)容完整繼承自 documentation/ar_EG/dependency_management.md并通過(guò)對(duì) lib/get_instance/src/extension_instance.dart、lib/get_instance/src/bindings_interface.dart、lib/get_core/src/smart_management.dart、lib/get_instance/src/lifecycle.dart 與 test/instance/get_instance_test.dart 等源碼和測(cè)試的對(duì)照對(duì)每種方法的底層參數(shù)、內(nèi)存行為與適用場(chǎng)景做了進(jìn)一步印證與擴(kuò)展。贊分享前端【免費(fèi)下載鏈接】getxOpen screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.項(xiàng)目地址https://gitcode.com/gh_mirrors/ge/getx點(diǎn)擊查看免費(fèi)下載相關(guān)推薦GetX 依賴管理完全指南Get.put、Get.lazyPut、Bindings 與 SmartManagement 的實(shí)戰(zhàn)與源碼解析GetX 依賴管理完全指南Get.put、Get.lazyPut、Bindings 與 SmartManagement 的實(shí)戰(zhàn)與源碼解析 GetX當(dāng)前倉(cāng)庫(kù)前端GetX 依賴管理完全指南從 Get.put 到 Bindings 的注入、生命周期與內(nèi)存管理GetX 依賴管理完全指南從 Get.put 到 Bindings 的注入、生命周期與內(nèi)存管理 GetX當(dāng)前倉(cāng)庫(kù) gh_mirrors/ge/getx 內(nèi)前端GetX 依賴管理Dependency Management完整指南Get.put、Bindings 與 SmartManagement 源碼級(jí)解析GetX 依賴管理Dependency Management完整指南Get.put、Bindings 與 SmartManagement 源碼級(jí)解析 Ge前端創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考