PDA

View Full Version : حذف فرم با Free و گاهی Error های ناجور



bmanfy
چهارشنبه 23 بهمن 1387, 11:50 صبح
سلام دوستان .
من تو برنامه ام فرمها رو در هر زمانی که نیاز باشه میسازم و بعد از اتمام کار با دستور Free از حافظه خارج میکنم .
اما گاهی یه سری خطاهایی میده . خطاهاش نامفهومه . و برای بازکردن دوباره اون فرمها باید برنامه را دوباره اجرا کنم .
کسی میدونه مشکل از چیه ؟

AliReza Vafakhah
چهارشنبه 23 بهمن 1387, 15:10 عصر
من Destory را امتحان کردم اما فرم را به طور کلی از حافظه خارج نمی کرد

اما از دستور FreeAndNil که استفاده کردم دقیقا فرم از حافظه خارج می شد

ببین FreeAndNil به کارت میاد



if (Form<>Nil) then
FreeAndNil(Form);



FreeAndNil(Object)

vcldeveloper
پنج شنبه 24 بهمن 1387, 02:42 صبح
من Destory را امتحان کردم اما فرم را به طور کلی از حافظه خارج نمی کرد

اما از دستور FreeAndNil که استفاده کردم دقیقا فرم از حافظه خارج می شد

ببین FreeAndNil به کارت میاد
این متدها و توابع کارهای مشابهی انجام میدند.
Destroy شی مورد نظر را آزاد میکنه. Free فرقش با Destroy اینه که قبل از فراخوانی Destroy چک میکنه که شی مربوطه nil نباشه، برای همین هم اگر یک شی nil شده را بخواین با free آزاد کنید، خطایی تولید نمیکنه. FreeAndNil هم یک تابع ساده هست که Free را فراخوانی میکنه، و بعد شی را nil میکنه، تا بعدا اگر با توابعی مثل Assigned بررسی کردید، اشتباها فکر نکنید شی مقدار داره.
پس این توضیحاتی که دادید درباره آزاد کردن کامل یا ناقص، درست نیست.

در ضمن، برای فراخوانی FreeAndNil یا Free، با توجه به توضیحاتی که دادم، نیازی نیست که چک کنید شی nil هست یا نه، چون خودِ Free این کار را انجام میده.

bmanfy
جمعه 25 بهمن 1387, 09:13 صبح
پس با توجه به توضیحاتی که دادین همه چیز به Free خطم میشه . و Free ظاهرا از همه بهتره . اما چرا گاهی اون جوری میکنه .
ببینید من دقیقا این کار رو کردم .
توی یک دکمه نوشتم فرم رو بسازه . به به صورت مدال نشون بده و بعد اون رو Free کنه .
وقتی مودال میشه دستور Free اجرا نمیشه . وارد فرم میشه . بعد از اینکه فرم با دستور close بسته میشه دستور Free انجام میشه .
به نظر شما تو این روند مشکلی هست ؟

AliReza Vafakhah
جمعه 25 بهمن 1387, 19:46 عصر
فکر کنم شما باید از دستور ModalResult هم جهت ارسال مدال به فرم اصلی استفاده کنید.

AliReza Vafakhah
جمعه 25 بهمن 1387, 19:54 عصر
این متدها و توابع کارهای مشابهی انجام میدند.
Destroy شی مورد نظر را آزاد میکنه. Free فرقش با Destroy اینه که قبل از فراخوانی Destroy چک میکنه که شی مربوطه nil نباشه، برای همین هم اگر یک شی nil شده را بخواین با free آزاد کنید، خطایی تولید نمیکنه. FreeAndNil هم یک تابع ساده هست که Free را فراخوانی میکنه، و بعد شی را nil میکنه، تا بعدا اگر با توابعی مثل Assigned بررسی کردید، اشتباها فکر نکنید شی مقدار داره.
پس این توضیحاتی که دادید درباره آزاد کردن کامل یا ناقص، درست نیست.

در ضمن، برای فراخوانی FreeAndNil یا Free، با توجه به توضیحاتی که دادم، نیازی نیست که چک کنید شی nil هست یا نه، چون خودِ Free این کار را انجام میده.

آقای کشاورز توضیحات شما درست اما من یه برنامه نوشتم که مجبور بودم مرتب شی TStringList را ایجاد کنم و سپس از حافظه خارج کنم شاید این دستور 200 بار اجرا میشد
من هم از free و هم از Destory استفاده کردم اما مشکل بزرگی که به وجود میومد این بود حافظه ای که برنامه من اشغال می کرد گاهی به 150MB می رسید و مشکل خیلی بزرگی بود
تا آخر این که در یه کتاب به دستور FreeAndNil برخوردم و این دستور مشکل را برطرف کرد
و باعث شد که برنامه فقط 25MB حافظه اشغال کند.

vcldeveloper
جمعه 25 بهمن 1387, 23:33 عصر
پس با توجه به توضیحاتی که دادین همه چیز به Free خطم میشه . نه دوست عزیز، همه چیز ختم به Destroy میشه، چون در نهایت Free متد Destroy را فراخوانی میکنه.


وقتی مودال میشه دستور Free اجرا نمیشه . وارد فرم میشه . بعد از اینکه فرم با دستور close بسته میشه دستور Free انجام میشه .اگر غیر از این رفتار می کرد، مشکلی وجود داشت! فلسفه نمایش فرم Modal همین هست که روال عادی اجرای برنامه تا زمان بسته شدن فرم Modal متوقف بشه. درباره Show و ShowModal تحقیق کنید.


آقای کشاورز توضیحات شما درست اما من یه برنامه نوشتم که مجبور بودم مرتب شی TStringList را ایجاد کنم و سپس از حافظه خارج کنم شاید این دستور 200 بار اجرا میشد
من هم از free و هم از Destory استفاده کردم اما مشکل بزرگی که به وجود میومد این بود حافظه ای که برنامه من اشغال می کرد گاهی به 150MB می رسید و مشکل خیلی بزرگی بود
تا آخر این که در یه کتاب به دستور FreeAndNil برخوردم و این دستور مشکل را برطرف کرد
و باعث شد که برنامه فقط 25MB حافظه اشغال کند. این دلیل نمیشه. این احتمال وجود داره که در بخشی از کد برنامه شما با استفاده از Assigned وضعیت متغیر مربوطه چک میشده، تا در صورت تخصیص نیافتن یک شی به آن، یک شی جدید ساخته شود. در این حالت، چون شما شی را بعد از آزاد شدن nil نمی کردید، تابع Assigned متوجه آزاد شدن شی نمی شد، و دائما شی جدیدی ساخته میشد. حالا که از FreeAndNil استفاده می کنید، او شی همیشه بعد از آزاد شدن nil هم میشه، و تابع Assigned همیشه نتیجه درستی برمیگردونه.
در واقع در نسخه قبلی کد شما Memory Leak وجود داشته که متوجه آن نشده بودید، و استفاده از FreeAndNil باعث شده که Memory Leak برطرف بشه.
بطور کلی خوب هست که به استفاده از FreeAndNil عادت کنید، نه بخاطر اینکه حافظه بیشتری آزاد میکنه، بلکه بخاطر اینکه همیشه بعد از آزاد کردن شی مورد نظر، آن را nil هم میکنه، و در شرط هایی که روی آن شی انجام میشه، دچار اشتباه نمشید.

برای اینکه بهتر متوجه بشید که Free و FreeAndNil چطور عمل می کنند، بهتر هست که سورس کد آنها را ببینید:


procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;در کد بالا، چک میشه که شی nil نباشه، اگر نبود، متد Destroy فراخوانی میشه.



procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;در کد بالا، ابتدا اشاره گری که به شی اشاره میکنه nil میشه، بعد شی Free میشه. علت استفاده از Temp هم این هست که با توجه به کد Free در بالا، اگر مستقیما شی را nil می کرد، متد Free هیچ وقت متد Destroy را فراخوانی نمی کرد

bmanfy
یک شنبه 27 بهمن 1387, 09:02 صبح
اگر غیر از این رفتار می کرد، مشکلی وجود داشت! فلسفه نمایش فرم Modal همین هست که روال عادی اجرای برنامه تا زمان بسته شدن فرم Modal متوقف بشه. درباره Show و ShowModal تحقیق کنید.

نه در مورد این که فلسفه مدوال به این شکله که میدونم . نه فقط منظورم این بود که فرم رو مدال کردم همین


نه دوست عزیز، همه چیز ختم به Destroy میشه، چون در نهایت Free متد Destroy را فراخوانی میکنه.

منظورم در مورد صدا زدن بود . یعنی اینکه همه گفته بودین از Free استفاده کنم .

bmanfy
یک شنبه 27 بهمن 1387, 09:04 صبح
اخرش کسی نفهمید چرا برنامه من خطا میده .
البته فکر میکنم آن خطاهایی که میده ادرسهایی از حافظه و ... باشه .
حالا اگه شد یک عکس از خطا میارم .

modrek
شنبه 03 اسفند 1387, 08:34 صبح
سلام به نظر من پیغام خطایی رو که میده بذار رو سایت تا ببینیم اصلا اشکال کجاست . انشا الله مشکلت حل میشه .