Sonunda mı yoksa başında super.initState'i aramalı mıyım?


12

Çırpınan yeri nereden arayacağım konusunda kafam karıştı super.initSate()? Bazı kod örneklerinde başlangıçta, diğerlerinde sonunda denir. Bir fark var mı?

Ben bu google denedim ama bu işlev çağrısı pozisyonu hakkında herhangi bir açıklama bulunamadı.

Hangisi doğru?

void initState() {
  super.initState();    
  //DO OTHER STUFF
}

veya

void initState() {    
  //DO OTHER STUFF
  super.initState();    
}

Yanıtlar:


7

Bu mixins için önemli (ve bu yüzden sizin için de)

Flutter çerçevesindeki a . Yaşam döngüsü yöntemlerini geçersiz kılarken süper yöntemi çağırmak bir paradigmadırState . Bu yüzden deactivatebir mustCallSuperek açıklama bile var .
Ayrıca , bazı mixinişlevlerde belirli bir noktada bu yaşam döngüsü yöntemleri süper yöntemleri çağırmak bekliyoruz.

Eğer dokümantasyon ve çağrıyı takip etmesi gerektiği Bu araçlar super.dispose sonunda sizin içinde disposeçünkü yöntemine mixinüzerinde lar Stateçerçevesinde bu olup bekliyoruz.
Örneğin: TickerProviderStateMixinve sonunda iddia edin:SingleTickerProviderStateMixin super.dispose

Super.dispose () öğesini çağırmadan önce tüm Tickersların [..] atılması gerekir.

Başka bir örnek: ve AutomaticKeepAliveMixinmantığını yürütür .initStatedispose

Sonuç

Başlat initStateilesuper.initState ve son senin disposeilesuper.dispose eklemeyi kolay ve güvenli tarafta olmak istiyorsanız mixinadresinden Müşteri s State.
Ayrıca, diğer yaşam döngüsü yöntemleri (üzerine Stateyazdığınız herhangi bir yöntem ) için belgeleri izleyin, çünkü çerçeve, belgede açıklandığı gibi süper yöntemleri çağırmanızı bekler.

Böylece, aşağıdakileri yapmanız gerekir:

void initState() {
  super.initState();    
  //DO OTHER STUFF
}

Ancak, gerçekten önemli değil State, aşağıda açıklayacağım ve mixins için bile, sadece ne bulabileceğimi değerlendiren iddialar için önemlidir - bu yüzden üretim uygulamanızı etkilemez.

Önemli değil State

Ben önceki iki cevabı olduğunu düşünüyorum Pablo Barrera ve CopsOnRoad edilir yanıltıcı işin gerçeği bu gerçekten önemli değildir ve uzağa bakmasına gerek kalmamasıdır çünkü.

Sadece eylemler super.initStateve super.disposealmak Statesınıfın kendisi olan iddialar ve o zamandan beri assert-statements sadece değerlendirilir ayıklama modunda , bu üretim modunda, yani bütün yapı bir kez uygulamanızı önemli değil.


Aşağıda, ek bir karışımınız olmadığında yürütülecek tüm kod olan ne super.initStateve ne super.disposeyapacağınız konusunda size rehberlik edeceğim State.

initState

super.initStateİlk olarak hangi kodun yürütüldüğüne bakalım ( kaynak ):

@protected
@mustCallSuper
void initState() {
  assert(_debugLifecycleState == _StateLifecycle.created);
}

Gördüğünüz gibi, yalnızca bir yaşam döngüsü iddiası var ve bunun amacı, widget'ınızın doğru şekilde çalışmasını sağlamaktır. Kendi başınıza bir super.initState yerde aradığınız sürece , widget'ınızın amaçlandığı gibi çalışıp çalışmadığını initStategöreceksiniz AssertionError. Önceden bir eylemde bulunmuş olmanız önemli değildir assert, çünkü kodunuzdaki bir şeyin zaten yanlış olduğunu bildirmek içindir ve super.initStateyönteminizin en sonunda arasanız bile bunu göreceksiniz .

dispose

disposeYöntemi (benzerdir kaynak ):

@protected
@mustCallSuper
void dispose() {
  assert(_debugLifecycleState == _StateLifecycle.ready);
  assert(() {
    _debugLifecycleState = _StateLifecycle.defunct;
    return true;
  }());
}

Gördüğünüz gibi, yalnızca hata ayıklama yaşam döngüsü denetimini işleyen iddialar da içerir . assertBurada ikincisi güzel bir hile çünkü _debugLifecycleStatesadece hata ayıklama modunda değiştirilmesini sağlar (çünkü assert-statements sadece hata ayıklama modunda yürütülür).
Bu , kendi yönteminizde bir super.dispose yerde aradığınız sürece, ek işlevsellik ekleyerek mixins olmadan hiçbir değer kaybetmeyeceğiniz anlamına gelir .


1
Çırpınan resmi dokümanlar çok iyi değil :( Cevabınız için teşekkürler :)
CopsOnRoad

Açıklamanız için teşekkürler, ayrıca açıklamak ister misiniz, initState()yöntemde sadece bir satır var assert(...), bu yüzden super.initState()üretim uygulamasında arama bile faydası nedir?
CopsOnRoad

1
Çok teşekkürler. Şimdi bir şey ifade ediyor! Bu yüzden daha güvenli tarafta olmak ve iyi programlama uygulamaları için kodun başında tutmak iyi olur.
K Vij

@creativecreatorormaybenot Bu, Flutter'ın mustCallSupervarlığından bu yana 2 yıldan fazla bir süredir bu yöntemi uygulayarak Flutter ekibinin aklından çıktığı anlamına geliyor . Oraya koymanın yararı nedir efendim?
CopsOnRoad

Takım için yarattı @creativecreatorormaybenot bile mixin, yine de bu tek ifadesi olacaksa olacak initStateolan assert(...)hatta çağıran önemi nedir yüzden, super.initState()bir üretim uygulamasına ilişkin?
CopsOnRoad

3

super.initState()her zaman initStateyönteminizdeki ilk satır olmalıdır .

Dokümanlar'dan:

initState (): Bunu geçersiz kılarsanız, yönteminizin super.initState () çağrısıyla başladığından emin olun.


2

Sınıflarda çerçeveden görebileceğiniz gibi, widget başlatıldıktan sonra her şeyi yapmalısınız, yani sonra super.initState().

Atma davası mantıklı bir şekilde başka bir şekilde olurdu, önce her şeyi yapın ve sonra arayın super.dispose().

@override
void initState() {
  super.initState();
  // DO STUFF
}

@override
void dispose() {
  // DO STUFF
  super.dispose();
}

Teşekkür. Ama bazı kod örneklerinde fark ettim. initState yönteminin sonunda çağrılır ...
K Vij

Ben de öyle dedim
Pablo Barrera

0

Widget ağacına her yeni durumlu widget eklendiğinde initState varsayılan olarak çağrılır. Şimdi super.initState, widget'ınızın temel sınıfının varsayılan uygulamasını gerçekleştirir. Temel sınıfa bağlı super.initState'den önce bir şey çağırırsanız, bu soruna neden olabilir. Bu nedenle initState'i bu şekilde çağırmanız önerilir:

@override
void initState() {
  super.initState();
  // DO STUFF
}

Akıl yürütme biraz kusurlu çünkü disposetam tersi. Çerçeve super.dispose sonunda sizi aramanızı bekliyor , ancak öneri doğru.
creativecreatorormaybenot

Çünkü super.dispose öğesini başka şeyleri atmadan önce çağırırsanız, temel sınıfınıza bağlı bileşenler çakışabilir.
Anirudh Sharma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.