Delphida modal shakllar uchun Release o'rniga Free dan foydalanish xavfsizmi?

Delphi onlayn yordamida aytilishicha, Release formani xotiradan olib tashlash uchun ishlatilishi kerak. Biroq, modal shakllar uchun ko'plab misollarda men ushbu konstruktsiyani ko'rdim:

MyForm := TMyForm.Create(nil);
try
  MyForm.ShowModal;
finally
  MyForm.Free;
end;

Bepul modal shaklni yo'q qilishning xavfsiz usulimi? ShowModal manbasida ko'rib turganimdek, ModalResult 0 bo'lmaguncha Application.HandleMessage chaqiriladi. Free-ning kutilayotgan Windows xabarlariga xalaqit bera olmasligining sababi shumi?


person mjn    schedule 27.05.2009    source manba
comment
Aloqador: stackoverflow.com/questions/274523/form-release-nil   -  person mjn    schedule 19.12.2011
comment
Eslatma: ikkilamchi Delphi shakllarini yopish bilan bog'liq Delphi xatosi mavjud. Bu ilovangizni buzadi: quality.embarcadero.com/browse/RSP-33140   -  person Z80    schedule 24.03.2021


Javoblar (3)


Ha, ShowModal chaqiruvidan keyin Free dan foydalanish xavfsiz.

Release dan foydalanishingiz kerak bo'lgan holatlar voqea ishlov beruvchisi (masalan, OnClick) o'rtasida bo'lgan vaqtlar bo'lib, hodisadan keyin keyingi ishlov berish formaga kirishga to'g'ri keladi. Bunday holda, Release ga qo'ng'iroq qilish o'rniga CM_RELEASE xabarini yuboradi, bu voqea ishlov beruvchisi tugaguncha va boshqaruv xabar pompasiga (ProcessMessages/Application.Run) qaytmaguncha voqeani bo'shatib qo'ymaydi. ShowModal voqea ishlovchisi tugaguniga qadar qaytmaydi va boshqaruv uni stekga zaxiralaydi, shuning uchun keyin Free ga qo'ng'iroq qilish CM_RELEASE xabari aks holda qayta ishlanadigan joy bo'ladi.

person Zoë Peterson    schedule 27.05.2009
comment
Hech qanday Application.ProcessMessages qo'ng'iroqlari bo'lmasligi uchun ehtiyot bo'ling! - person Gerry Coll; 28.05.2009
comment
@GerryColl Nima uchun? Va aniq qayerda? - person Bozzy; 24.09.2015
comment
@Bozzy Agar Release dan foydalansangiz va keyin Application.ProcessMessages raqamiga qo'ng'iroq qilsangiz, WM_RELEASE xabari qayta ishlanadi va shakl bo'shatiladi. Gerryning tashvishi shundaki, agar siz vayron qilishni kechiktirish uchun Release-dan foydalanayotgan bo'lsangiz, so'ngra arizani tugatmasdan oldin tasodifan bo'shatib qo'ysangiz. - person Zoë Peterson; 24.09.2015

Vaziyatga bog'liq. Freeshaklni kiritish Release kabi hodisa ishlov beruvchilarini chaqirmaydi va formaga joylashtirilgan va navbatda turgan xabarlar qayta ishlanmaydi. Shunday qilib, ko'p va ehtimol ko'p hollarda Free (yoki FreeAndNil) ga qo'ng'iroq qilish yaxshi ishlaydi, lekin tasodifiy ko'rinadigan sabablarga ko'ra juda g'alati xatti-harakatlarga olib kelishi mumkin.

Men taklif qiladigan alternativa OnClose tadbirida Action-ni caFree-ga o'rnatdi, masalan:

procedure FormClose(Sender : TObject; Action : TCloseAction)
begin
  Action := caFree;
end;

Keyin shunday kod yozishingiz mumkin:

TMyForm.Create(nil).ShowModal;

Shaklni maxsus bo'shatishning hojati yo'q, chunki u tugagandan so'ng o'zini ozod qiladi.

person Tim Sullivan    schedule 27.05.2009
comment
Menga bu ijodkorlik yoqadi, lekin men uni hech qachon ishlatmayman, chunki savolda ko'rsatilgan kod buni amalga oshirishning idiomatik usulidir - sizning kodingiz bilan men har doim bir necha oydan keyin qoqilib qolganda forma to'g'ri bo'shatilganmi deb hayron bo'lardim. - person mghie; 27.05.2009
comment
Meh, nimani his qilsangiz, eng yaxshisi. Biroq, bu shaklning funksionalligini to'liq qamrab oladi va uni bo'shatishni unutish imkoniyatini kamaytiradi. - person Tim Sullivan; 27.05.2009
comment
Harakatni caFree-ga o'rnatish shunchaki Release-ni chaqiradi. Agar biror narsa (buzilganmi?) ProcessMessages qo'ng'iroqlari bo'lsa, ko'rsatuvdan keyin shaklning xususiyatlariga kirishni istasangiz, ehtiyot bo'lishingiz kerak. - person Gerry Coll; 28.05.2009
comment
CM_Release usuli oddiygina Free() ni chaqiradi, nima uchun formani bo'shatish Release bajaradigan voqea ishlov beruvchilarini chaqirmaydi deysiz? - person Darian Miller; 30.05.2009

Albatta, va siz FreeAndNil tartibidan ham foydalanishingiz mumkin. FreeAndNil tartibi ob'ektni faqat nolga teng bo'lmagan taqdirda bo'shatadi va bo'sh bo'lgandan keyin uni nolga o'rnatadi. Agar siz allaqachon bo'shatilgan ob'ektga to'g'ridan-to'g'ri bepul qo'ng'iroq qilsangiz, siz kirish buzilishini olasiz.

MyForm := TMyForm.Create(nil); 
try 
  MyForm.ShowModal; 
finally 
  FreeAndNil(MyForm); 
end;
person skamradt    schedule 27.05.2009
comment
Kichik nitpik: Free ham ob'ektni bo'shatadi, agar u nol bo'lmasa, ikkinchi qism muhim bo'lsa. - person mghie; 27.05.2009
comment
Agar MyForm mahalliy o'zgaruvchi bo'lsa, FreeAndNil() dan foydalanish, albatta, ortiqcha. MyForm.Free yetarli, aslida MyForm.Destroy ham xuddi shunday ishlaydi. - person Allen Bauer; 27.05.2009
comment
+for Allen - FreeAndNil-dan ortiqcha foydalanish kompilyator tomonidan topilgan xatolarni yashirishi mumkin - agar ob'ekt ishga tushirilmagan bo'lsa (odatda shartli yaratish) shikoyat qilmaydi. Bu ham savolga javob bermaydi (HA IT IS OK). - person Gerry Coll; 28.05.2009
comment
Bu erda allaqachon ozod qilingan ob'ektga Free chaqirilishi xavfi bormi? Agar yo'q bo'lsa, FreeAndNil-dan foydalanish unchalik yaxshi emas. Agar xavf mavjud bo'lsa, FreeAndNil baribir bu holatda yordam bermaydi. (Yodingizda bo'lsin, siz o'zgaruvchilar emas, balki ob'ektlarni bo'shatib qo'yasiz. MyForm ob'ekt emas, o'zgaruvchidir.) - person Rob Kennedy; 28.05.2009
comment
Mening taxminlarimga ko'ra, MyForm birlik birinchi yaratilganida muharrir tomonidan yaratilgan global o'zgaruvchidir. Men Allenning fikriga qo'shilaman AGAR o'zgaruvchi to'liq mahalliy bo'lsa, u holda o'zgaruvchi doiradan chiqib ketgani uchun .free etarli bo'ladi. - person skamradt; 29.05.2009