Pure Coder
786 subscribers
189 photos
30 videos
8 files
150 links
⭕️آدرس سایت:
https://purecoder.ir

⭕️گروه پرسش و پاسخ:
@purecoder_gp

⭕️پشتیبانی:
@PureCoder_support
@MohammadTaherri
Download Telegram
Quiz
کوییز(سطح آسان)
وقتی برای اولین بار یه State class ساخته میشه کدوم یک از موارد زیر قبل از همه اجرا میشه؟
Anonymous Quiz
50%
State constructor
42%
initState
8%
build
Quiz
کوییز(سطح متوسط)
در اولین اجرای یه State class کدوم متد بعد از initState و قبل از build اجرا میشه؟
Anonymous Quiz
29%
didUpdateWidget
47%
didChangeDependencies
24%
activate
Quiz
کوییز (سطح متوسط)
توی یه State class تصمیم دارم یه سری color تعریف و اون رو با استفاده از theme مقدار دهی کنم. توی کدوم یک از متد های زیر Theme.of رو صدا بزنم؟ ( دلیل انتخابت رو کامنت کن)
Anonymous Quiz
32%
initState
26%
didUpdateWidget
35%
didChangeDependencies
8%
activate
Quiz
کوییز (سطح متوسط)
ایا در یه State class همیشه قبل از متد dispose متد deactivate اجرا میشه؟
Anonymous Quiz
41%
بله
59%
خیر
⚡️چرخه حیات State ، مختصر ، کامل و دقیق⚡️

1⃣mount
اولین بار که یک stateful ساخته میشه و توی درخت قرار میگیره متد های زیر از state به ترتیب اجرا میشن :
State Constructor

initState
didChangeDependencies
build

توی هر سه متد بالا به context دسترسی داریم و میتونیم با context کار کنیم.
برخلاف تصور و اشتباه رایج خیلی ها که میگن داخل initState به context دسترسی نداریم.
🔥فقط اگه میخاستیم به یه inheritedWidget وابسته بشیم مثلن theme.of رو صدا بزنیم این کار رو باید توی دو متد didChangeDependencies یا build انجام بدیم.
🔥همیچنین توی متد های بالا با استفاده از پروپرتی widget میتونیم به ویجت این State دسترسی داشته باشیم.

2⃣setState
هر بار که توی استیت setState صدا زده بشه متد build یکبار دیگه اجرا میشه.

3⃣update
هر بار که ویجت parent این stateful این ویجت رو با یه کانفیگ جدید اپدیت کنه متدهای زیر اجرا میشن :
didUpdateWidget (Widget oldWidget)
build

ویجت parent این ویجت اپدیت شده و child خودش که همین stateful ما هست رو با یه ویجت جدید از همین type اپدیت کرده (ویجت ها immutable هستن)
در نتیجه didUpdateWidget اجرا میشه که به state اطلاع بده که ویجتت اپدیت شده.
توی ورودی هم ویجت قبلی (stateful قبلی /oldWidet) رو بهش میده.
ویجت جدید هم از طریق پروپرتی widget قابل دسترسیه.

4⃣dependencies changed
اگه این ویجت به یه InheritedWidget وابسته شده باشه مثلن Theme.of رو با context خودش صدا زده باشه.
هر بار که اون InheritedWidget اپدیت بشه و این اپدیت شدن رو به درخت زیر خودش نوتیف بده متد های زیر به ترتیب اجرا میشن :
didChangeDependencies
build

5⃣deactivate
هر بار که ویجت parent این ویجت تصمیم بگیره این نقطه از درخت رو با یه ویجت جدید جایگزین کنه یا کلن این ویجت رو حذف کنه و دیگه این ویجت بدردش نخوره این ویجت رو غیر فعال میکنه و از درخت حذف میکنه و در این مرحله متد زیر اجرا میشه :
deactivate

🔥در این مرحله هنوز متد dispose اجرا نمیشه و فقط deactivate اجرا میشه.

6⃣activate
اگه به این ویجت یه GlobalKey داده باشیم بعد از deactivate شدن ممکنه یه جای دیگه از درخت (با یه parent) دیگه به یه ویجت از این نوع و همین GlobalKey نیاز داشته باشه.
در نتیجه این ویجت activate میشه و توی اون نقطه از درخت مورد استفاده قرار میگیره و parent اش نسبت به قبل تغییر میکنه.(این اتفاق یعنی پیوند زدن به یه جای دیگه درخت حتمن باید توی همین فریم اتفاق بیفته که ویجت deactivate شده)
درنتیجه متد زیر توی state اجرا میشه :
activate
بعد از این متد هم متد
build
اجرا میشه و اگه این ویجت توی اجرای قبلی به یه inheritedWidget وابسته شده باشه قبل build هم متد زیر اجرا میشه :
didChangeDependencies
پس یا :
activate
build
یا
activate
didChangeDependencies
build
بسته به شرایط اجرا میشن.

7⃣unmount
اگه بعد از deactivate شدن و تا پایان این فریم این ویجت به هیچ جای دیگه پیوند نخوره (GlobalKey نداشته باشه یا لازم نشه که پیوند بخوره) متد زیر اجرا میشه :
dispose
و state برای همیشه میره پی کارش و غیر قابل استفاده میشه.

پس بلافاصله بعد از متد deactivate متد dispose اجرا نمیشه.
یه فاصله ای بینشون هست.
فاصله خیلی کم و در حد میلی ثانیه هست ولی بین اجرای این دو فاصله هست.

🔥همیشه قبل از dispose متد deactivate اجرا میشه ولی الزامن همیشه بعد از deactivate متد dispose اجرا نمیشه.

پس :
🔥توی initState هم به context دسترسی داریم.

🔥وابسته شدن به InheritedWidget رو حتمن توی didChangeDependencies یا build انجام میدیم.

🔥توی متد های deactivate و dispose کارهایی که مربوط به context میشه رو انجام نمیدیم (چون widget tree اون موقع statble نیست و در واقع این ویجت parent خودش رو از دست داده و parent نداره)

🔥کارهایی مثل dispose کردن کنترلر ها و ... رو توی متد dispose انجام میدیم و نه deactivate چون بعد از deactivate ممکنه دوباره به درخت برگرده و reperent بشه.

🔥در صورتی که ویجت GlobalKey داشته باشه (فقط GlobalKey) ممکنه بعد از deactivate شدن reparent بشه و به یه parent دیگه پیوند بخوره و مجددن activate بشه(که در این صورت state حفظ میشه)

#state_life_cycle
#quiz
#state_life_cycle

توی کد بالا یه کلاس HomePage از نوع استیت فول داریم که از یه اسکفلد تشکیل شده که توی body اون یه استیت فول دیگه به اسم HomePageBody قرار داره و یه floatingActionButton هم داریم که با تپ کردنش setState روی Homepage اعمال میشه....
⚡️⚡️یه نکته ⚡️⚡️
کد بالا رو نگاه کنید.
یه کلاس Point داریم که دو تا instance field داریم به اسم های x و y که توی constructor مقدار گرفتن.

یه instance field دیگه هم داریم
distanceToOrigin
که میخوایم اون رو با استفاده از دو تا فیلد دیگه مقدار بدیم.

ولی بهمون ارور میده چون که نمیتونیم از یه instance field برای مقدار دهی یه instance field دیگه استفاده کنیم.

🤔🤔راه حل چیه؟
🔥راه حل اول استفاده از getter هست
double get distanceToOrigin => ....

و به این روش میشه از مقادیر instance field های دیگه داخل این getter استفاده کرد.
چون که getter یه متد هست و داخلش میشه از instance field های کلاس استفاده کرد.
🔥راه حل دوم استفاده از late هست.
late final distanceToOrigin = ...

در این حالت distanceToOrigin هم یه instance field هست ولی چون از late استفاده کردیم همون اول کار که از کلاس ابجکت ساخته میشه مقدار دهی نمیشه و اولین باری که میخوایم از این فیلد استفاده کنیم مقدار دهی میشه.

در این حالت امکان استفاده از const constructor نیست.
چرا؟ 🤔
🔥کاربرد :
کاربرد دو راه حل بالا :

توی State یه Stateful
جایی که میخوایم توی یه فیلد از پروپرتی widget استفاده کنیم.

مثلن :
Color color = widget.color:
که به مشکل میخوریم.
که با استفاده از getter و یا late میشه برطرفش کرد.
Color get color => widget.color;

Or

late Color color = widget.color;

توی abstract classها (که میخوایم constructor نداشته باشن و فقط یه interface باشن) هم میتونیم بعضی فیلد ها رو با توجه به فیلد های دیگه مقدار بدیم.

و...
🔥راه حل سوم هم میتونه استفاده از از initializer list توی constructor کلاس باشه. ( جاهایی که امکانش وجود داره)
۷ آبان روز بزرگداشت کوروش کبیر گرامی باد

هفتم آبان، سالروز ورود کوروش بزرگ به بابل می‌باشد. بر اساس رویدادنامه نبونعید، در ۲۹ اکتبر (۷ آبان) سال ۵۳۹ پیش از میلاد کوروش وارد بابل شد. در رویدادنامه نبونعید اینچنین آمده است:

در ماه اَرَخسمنو (Arahsamnu = ماه هشتم)، روز سوم (هفتم آبان ماه) کوروش به بابل اندر آمد. شاخه‌های سبز در برابر (زیر پای او) گسترده شد.

این روز به مناسبت پایان تصرف امپراتوری بابل به دست سپاه هخامنشیان و پایان دوران ستمگری در جهان باستان انتخاب شده است.


Join → @Aparat_Tv 📺
⚡️⚡️یه نکته ⚡️⚡️
توی زبان دارت چیزی به صورت صریح به اسم interface نداریم و هر کلاسی میتونه در حکم یک interface عمل کنه.
یعنی با implement کردن یک کلاس به جای extend کردن میتونیم از اون کلاس به عنوان interface استفاده کنیم.

✔️پس یه کلاس توی دارت هم قابلیت ارث بری داره و هم اینکه میشه به عنوان interface ازش استفاده کرد.

🔥حالا اگه بخوایم یه کلاسی بنویسیم که فقط و فقط یه interface باشه باید چکار کنیم؟
یعنی اینکه کلاسمون نه قابلیت ارث بری داشته باشه و نه بشه ازش نمونه ساخت و دقیقن مثل یک interface فقط بشه implement اش کرد.

برای اینکار از پترن ساده زیر استفاده میکنیم.

abstract class MyInterface {

MyInterface._() ;

}

😍یعنی با یه private constructor امکان نمونه ساختن و ارث بری رو ازش میگیریم و فقط میتونیم implement اش کنیم.
Pure Coder
https://vrgl.ir/Qh1ip
دوستانی که بک اند کار میکنن میتونن این مقاله رو مطالعه کنن.
برای برنامه نویسان فلاتر هم خوندنش خالی از لطف نیست.
توی پست قبلی یکی از دوستان گفتن که در مورد class و interface و extend و implement ... کاربرد ها و تفاوت هاشون و... صحبت کنیم.
آیا کلن لازم میدونید که در مورد مباحث پایه ای دارت صحبت کنیم؟
Anonymous Poll
83%
آره خیلی خوبه
4%
نه لازم نیست
13%
نظری ندارم
⚡️⚡️debug vs profile vs release⚡️⚡️

توی فلاتر سه حالت برای خروجی گرفتن و اجرا کردن اپ داریم.
✔️debug
✔️profile
✔️release

حالت release که برای خروجی گرفتن نهایی و انتشار اپلیکیشن هست.

ولی چه تفاوتی بین حالت debug و profile هست ؟

🔥یکی از نکات مهم این هست که برای تست پرفرمانس اپ و بررسی مشکلات احتمالی و به اصطلاح لگ هایی که ممکنه موقع کار با اپ پیش بیاد باید از حالت profile استفاده کنیم.

چرا؟

🔥یکی از دلایل این هست که در حالت debug برای کمک به روند توسعه و خطایابی بهتر تعداد زیادی assert هنگام اجرای کد های فریمورک اجرا میشه که باعث افت پرفرمانس اپ در حالت debug میشه که این assert ها در حالت profile و release هیچ تاثیری ندارن.

🔥پس برای تست پرفرمانس اپ به هیچ وجه از حالت debug استفاده نکنید چون که ۱۰۰ درصد نتیجه نادرست خواهد بود.

🔥نکته دیگه این که برای اینکه بهترین تست پرفرمانس رو داشته باشید از دیوایس واقعی استفاده کنید.
پس
Profile mode + Real device

🔥همچنین میتونید از ابزارهایی که فلاتر در حالت profile در اختیارتون میگذاره برای تست پرفرمانس اپ و... استفاده کنید.
⚡️⚡️⚡️set get in Dart⚡️⚡️⚡️

اگه بخوایم این قاعده رو در دارت پیاده کنیم باید فیلد مورد نظر رو private کنیم و بعدش setter و getter تعریف کنیم.

String get name => _name;
String _name;
set name(String value) {
if(_name == value) return;
_name = value;
}

🔥ترتیبی که معمولن استفاده میکنن برای نوشتن کدها به شکل بالا هست.
✔️اول getter
✔️بعد فیلد private
✔️بعد setter

الزامی نیست ولی میتونید این ترتیب رو رعایت کنید. 😊

ولی ایا توی دارت همیشه نیازی به تعریف setter و getter داریم؟
نه.

مثلن وقتی که فیلد مورد نظر final هست (که قاعدتن read-only هم میشه) نیاز نیست که دیگ setter و getter تعریف کنیم.

یه نمونه واضح بخوایم مثال بزنیم ویجت های فلاتر هست.
همه ویجت ها immutable هستن و باید فیلد هاشون final باشن.
خب وقتی که یه ویجت جدید رو ایجاد میکنیم (فرقی نداره چه نوعی باشه) کافیه فقط یه سری فیلد final تعریف کنیم.

🔥به صورت واضح تر بخوایم بگیم توی دارت هر instance field خودش به صورت ضمنی (implicit) هم یه getter هست و هم یه setter.

یعنی وقتی که توی یه کلاس یه فیلد جدید تعریف میکنید برای مثال :
String name;
این فیلد خودش هم setter هست و هم getter.
و نیازی نیست که دیگه به صورت جداگانه براش setter یا getter تعرسف کنیم.

زمانی هم که فیلد رو final کنیم read-only میشه.

پس با این حساب توی دارت چه وقتایی setter یا getter تعریف کنیم؟

✔️زمانی که میخوایم توی این متد ها یه کاری اضافه تر از return کردن مقدار (getter) یا ثبت مقدار (setter) انجام بدیم.

✔️زمانی که لازمه فیلد مورد نظر write-only بشه.

✔️زمانی که لازم داریم یه field جدید علاوه بر instance field های قبلی به کلاس اضافه کنیم.
مثلن یه فیلدی که قراره از instance field های دیگه استفاده کنه.

String firstname;
String lastname;

String get fullname => '$firstname $lastname';

✔️توی abstract class ها هم وقتی که یه فیلدی داریم که قراره توی کلاس های فرزند تعیین تکلیف و مقدار دهی بشه معمولن از یه getter به صورت abstract استفاده میکنیم.

String get name;

و کلاس های فرزند اون رو override میکنن.

این نکته رو توی بحث abstraction بیشتر توضیح میدیم.