PDA

View Full Version : ?TForm.Create(?) Nil, Self or Application



m-khorsandi
شنبه 21 بهمن 1385, 23:49 عصر
[AOwner ?= [Nil, Self, Application

هنگام ایجاد یک شیئ در زمان اجرا (Run-Time) که از کلاس TControl مشتق شده مانند یک فرم (TForm) ، متد Create در انتظار یک پارامتر به عنوان "مالک" یا Owner کلاس هست. چه مقداری برای این پارامتر به عنوان مالک می‌بایست ارسال شود؟

فرض کنید فرمی به نام TMyForm در برنامه‌تان دارید، و می‌خواهید در زمان اجراء یک شیئ از این کلاس بسازید و استفاده کنید. به کلاس پدر TMyForm یعنی کلاس TForm برمی‌گردیم، این کلاس متدی به نام Create دارد ، که وظیفه ی ساخت و مقداردهی اولیه یک شیئ جدید که از TForm یا هر کلاس دیگری که از TForm مشتق شده را دارد:

http://i11.tinypic.com/47ul0zt.gif


در اینجا، پارامتر AOwner، مالک شیئ هست. مالک(Owner) فرم ، مسئول آزاد سازی حافظه تخصیص داده شده به شیئ فرم در موقع لزوم هست. زمانیکه مالک فرم از بین برود ، به صورت خودکار فرم نیز از بین می‌رود و این موضوع برای تمامی کلاسها صادق ست.

نکته مهم اینست که ، کدام یکی از مقادیر Application ، Self وnil را میبایست به عنوان پارامتر ارسال کنید؟
برای رسیدن به جواب ، ابتدا باید معنی و مفهوم کلمات application, nil, self را بدانیم.


nil : مشخص می‌کند که هیچ شیئ مالک فرم نیست و بنابراین ، برنامه نویس (شما) ، وظیفه دارد فرم ساخته شده را آزاد کند. مثلاً زمانی که دیگر نیازی به فرم ندارید می‌توانید با دستور myForm.Free ، حافظه مورد استفاده فرم را آزاد کنید.

درباره ی nil : nil یک ثابت خاص، جهت تخصیص به انواع اشاره‌گرهاست. nil، اختصار کلمه ی لاتین Nihil هست، که معنی آن هیچی یا صفر هست، بعضی‌ها هم می‌گویند nil به معنی Not In List هست. اشاره‌گری که مقدار nil دارد، هرگز به حافظه ی معتبری اشاره نمی‌کند، اما چون این اشاره‌گر تعریف شده و برای آن حافظه‌ای رزرو شده، بعضی از متدها می‌توانند آن را تست کنند (مانند تابع assigned). نمی‌توانید تفاوتی بین یک اشاره‌گر که مقداردهی اولیه نشده و یک اشاره‌گر که مقداردهی اولیه ی آن انجام گرفته بیابید، در واقع راهی برای تشخیص وجود ندارد. در دلفی nil دارای مقدار 0/صفر هست و اشاره به اولین بایت حافظه دارد که ظاهراً این بایت در اختیار کدهای دلفی قرار نمی‌گیرد.


Self : مشخص کننده شیئی ست که متد Create را فراخوانی کرده (Self اشاره‌گری ست به کلاس جاری) ، فرض کنید در فرمی با نام MainForm هستید و می‌خواهید شیئ MyForm را بسازید، روی دکمه ای کلیک می‌کنید و کد مورد نظر را می‌نویسید، در اینجا Self به کلاس MainForm اشاره دارد و نه دکمه‌ای که کد را روی آن نوشتید(در واقع دکمه، فیلدی از کلاس MainForm هست). بنابراین Self مساوی ست با MainForm ، پس هر زمانیکه MainForm از بین برود(آزاد شود) ، MyForm نیز از بین می‌رود(آزاد می‌شود).


Application : مشخص کننده یک متغیر عمومی از نوع کلاس TApplication هست و زمانی ایجاد می‌شود که برنامه‌تان را اجرا می‌کنید و در زمان خاتمه برنامه نیز به همراه تمام اشیائی که مالکشان هست از بین می‌رود. ایجاد و حذف آن بر عهده ی شما نیست و از این بابت نگران نباشید. این کلاس و شیئ به ترتیب در یونیت Forms تعریف و در یونیت Controls ساخته می‌شود.کلاس TApplication هم یک کامپوننت هست اما در زمان طراحی نمی‌توانید از آن استفاده کنید. بعضی از ویژگی‌های Application را می‌توانید مستقیماً در صفحه Application فرم Project Options تنظیم کنید، برای مابقی تنظیمات هم، می‌بایست از کد استفاده کنید.

مثال :
1 - Modal form ها (فرمهایی که تا وقتی بسته نشوند ، ادامه اجرای برنامه مقدور نمی‌باشد و این به معنی مرگ برنامه نیست، بلکه کاربر می‌بایست/می‌تواند فرم را ببندد - متد ShowModal ) : زمانی که باید نمایش داده شوند ، ساخته می‌شوند و بعد از بستن فرم توسط کاربر ، حافظه مربوطه آزاد می‌شود. در این نوع فرمها می‌توان از پارامتر nil به عنوان مالک (Owner) استفاده کرد ، چون بعد از بستن فرم ، آزاد کردن حافظه بر عهده برنامه نویس هست :



var
myForm : TMyForm;
begin
myForm := TMyForm.Create(nil) ;
try
myForm.ShowModal;
finally
myForm.Free;
end;
end;


2 - Modaless Form ها (زمانی که می‌بایست از چند فرم به طور همزمان استفاده کرد، کاربرد دارند - متد Show) : در این نوع فرمها می‌توانید از پارامتر Application به عنوان مالک (Owner) استفاده کنید :


var
myForm : TMyForm;
...
myForm := TMyForm.Create(Application) ;


در زمان خاتمه ی برنامه ، شیئ Application حافظه مربوط به myForm را آزاد خواهد کرد.


چرا و چه موقع استفاده از (TMyForm.Create(Application پیشنهاد نمی‌شود ؟
می‌توانید application را پاس دهید، ولی وقتی این کار را انجام می‌دهید هر کامپوننت و فرمی که به طور مستقیم و غیر مستقیم ، application، مالک آن هست، می‌بایست از این عمل با خبر شود، پس نوعی آگاه سازی نسبت به این کامپوننتها و فرمها صورت میگیرد و اگر تعداد شان زیاد باشد (مثلاً چندین فرم و هزار کامپوننت) با تاخیر زمانی قابل توجهی در هنگام نمایش فرم روبرو خواهیم شد. در این جور مواقع بهتر است که از nil به جای application استفاده کنیم تا هم فرم سریعتر ظاهر شود و هم تاثیری در کد نخواهد داشت.


3 – چه وقتی از self استفاده کنیم ؟ اگر فرم مورد نیاز شما از نوع Modal نیست و همچنین فرم اصلی برنامه هم نیست، اگر از self به عنوان مالک(Owner) استفاده کنید، با بسته شدن مالک(Owner)، فرم ساخته شده نیز فوراً آزاد می‌شود. معمولاً هنگام ایجاد یک فرم ، نباید از self استفاده کنید، در عوض از application یا nil استفاده کنید ، تفاوتی هم ندارد که modal یا modaless باشد. اما، از self زمانی استفاده کنید که نمی‌خواهید فرم ، طول عمری بیشتر از سازنده یا مالکش داشته باشد.

مهدی کرامتی
یک شنبه 22 بهمن 1385, 09:56 صبح
برادر خورسندی،

ضمن عرض تشکر بابت زحمات شما، خوب است متن مقاله را در تاپیک قرار دهید تا در فوروم قابل خواندن باشد، نسخه PDF مقاله را نیز ضمیمه کنید (برای آنهایی که خواندن PDF را ترجیح میدهند).