Flutter學習-GetX-05 生命週期

語言: CN / TW / HK

highlight: androidstudio

攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第7天,點選檢視活動詳情

本文主要介紹下Getx中關於值的生命週期和狀態管理的生命週期

之前介紹了關於依賴注入的2種方式,可以是直接建立或者懶載入的方式。這裡關於控制器共享的情況:

js Class a => Class B (has controller X) => Class C (has controller X) 在A類中,控制器還沒有進入記憶體,因為你還沒有使用它(Get是懶載入)。在類B中,你使用了控制器,並且它進入了記憶體。在C類中,你使用了與B類相同的控制器,Get會將控制器B的狀態與控制器C共享,同一個控制器還在記憶體中
如果你關閉C屏和B屏,Get會自動將控制器X從記憶體中移除,釋放資源,因為a類沒有使用該控制器。如果你再次導航到B,控制器X再次進入記憶體,如果你沒有去C類,而是再次回到a類,Get將以同樣的方式將控制器從記憶體中移除。 如果類C沒有使用控制器,你把類B從記憶體中移除,就沒有類在使用控制器X,同樣也會被處理掉。
唯一能讓Get亂了陣腳的例外情況,是如果你意外地從路由中刪除了B,並試圖使用C中的控制器,在這種情況下,B中的控制器的建立者ID被刪除了Get被設計為從記憶體中刪除每一個沒有建立者ID的控制器。如果你打算這樣做,在B類的GetBuilder中新增 "autoRemove: false "標誌,並在C類的GetBuilder中使用adopID = true

1. 值的生命週期

之前介紹ObxGetX等中其中Workers是監聽值的生命週期,Workers將協助你在事件發生時觸發特定的回撥``js ///每次count1`變化時呼叫。 ever(count1, () => print("$ has been changed"));

///只有在變數$第一次被改變時才會被呼叫。 once(count1, () => print("$_ was changed once"));

///防DDos - 每當使用者停止輸入1秒時呼叫,例如。 debounce(count1, () => print("debouce$"), time: Duration(seconds: 1));

///忽略1秒內的所有變化。 interval(count1, () => print("interval $"), time: Duration(seconds: 1)); `` 所有worker都會返回一個Worker例項,你可以用它來取消(通過dispose()`)worker。

  • ever :每當 Rx 變數發出一個新的值時,就會被呼叫。
  • everAll :和 ever 很像,但它需要一個 Rx 值的List,每次它的變數被改變時都會被呼叫。就是這樣。
  • once :once只在變數第一次被改變時被呼叫。
  • debounce :debounce搜尋函式中非常有用,你只希望API在使用者完成輸入時被呼叫。如果使用者輸入 "Jonny",你將在API中進行5次搜尋,分別是字母J、o、n、n和y。使用Get不會發生這種情況,因為你將有一個 "debounce "Worker,它只會在輸入結束時觸發
  • interval :interval 與 debouce不同,debouce如果使用者在1秒內對一個變數進行了1000次修改,他將在規定的計時器(預設為800毫秒)後只發送最後一次修改。Interval則會忽略規定時間內的所有使用者操作。如果你傳送事件1分鐘,每秒1000個,那麼當用戶停止DDOS事件時,debounce將只發送最後一個事件。建議這樣做是為了避免濫用,在使用者可以快速點選某樣東西並獲得一些好處的功能中(想象一下,使用者點選某樣東西可以賺取硬幣,如果他在同一分鐘內點選300次,他就會有300個硬幣,使用間隔,你可以設定時間範圍為3秒,無論是點選300次或100萬次,1分鐘內他最多獲得20個硬幣)。debounce適用於防DDOS,適用於搜尋等功能,每次改變onChange都會呼叫你的api進行查詢。Debounce會等待使用者停止輸入名稱,進行請求。如果在上面提到的投幣場景中使用它,使用者只會贏得1個硬幣,因為只有當用戶暫停到既定時間時,它才會被執行。

注意:Worker應該總是在啟動ControllerClass時使用,所以應該總是在onInit(推薦)、Class建構函式或StatefulWidgetinitState(大多數情況下不推薦這種做法,但應該不會有任何副作用)。

```js class GetXHomeController extends GetxController {

var count = 0.obs;

add(){ count.value++; } @override void onInit() { super.onInit();

ever(count, (callback) => print('ever:${count.value}'));

once(count, (callback) => print('once${count.value}'));

debounce(count, (callback) =>  print('debounce${count.value}'),time: const Duration(seconds: 1));

}

} `` 用於一些搜尋處理,或者點選頻率`處理。

2. contrlller的生命週期

  • GetBuilder替代StatefulWidget

在開發中我們可能會在Widget初始化的時候做些操作比如請求資料,如果是StatefulWidget則在initState中進行建立請求。或者在dispose()中呼叫某些方法。現在可以在GetBuilder中進行操作 js GetBuilder<Controller>( initState: (_) => Controller.to.fetchApi(), dispose: (_) => Controller.to.closeStreams(), builder: (s) => Text('${s.username}'), ), 但是最好還是在控制器中做相對應的操作 ```js @override void onInit() { fetchApi(); super.onInit(); }

///關閉流用onClose方法,而不是dispose @override void onClose() { user.close(); name.close(); super.onClose(); }

```

onInit類似我們iOS中的viewDidLoadonClose則類似dealloc方法

控制器的生命週期。 - onInit()建立控制器的地方。 - onReady()在建立成功後馬上呼叫 - onClose(),關閉控制器,為刪除方法做準備。 - deleted: 你不能訪問這個API,因為它實際上是將控制器從記憶體中刪除。它真的被刪除了,不留任何痕跡。

3. 小結

針對值的生命週期contrrller的生命週期我們選擇在合適的時機使用對應的方法,其中如果我們想要達到頁面返回是重新整理,或者請求可以通過 var result = await Get.toNamed()拿到結果進行操作。