منظور از self := nil برای زمانی بود که بخواییم داخل خود کلاس مورد نظر آزادش کنیم یعنی تو TForm2 که نمونش تو کد زیر هست
نکته اول اینکه Self به Form اشاره می کنه، نه به متغیر ما
نکته دوم اینکه با برابر nil قرار دادن یک اشاره گر، اون رو Free نمی کنید، اصولا یک اشاره گر Free نمیشه، بلکه مکانی که اشاره گر به اون اشاره می کنه Free میشه، نه خود اشاره گر
self = nil هیچ کاری انجام نمیده و چیزی رو آزاد نمی کنه و ارتباطی به آزاد کردن کلاس نداره، Free کردن با برابر nil قرار دادن تفاوت داره
TForm1.MyOnCloseTForm
begin
Action:= Cafree;
Sender:= nil;
end;
Sender = nil هم به همین ترتیب، Sender اینجا متغیر frm نیست، بلکه خود فرم هستش، تفاوتی با Self = nil نمی کنه ، چون اجرا کننده ی Event هم همون Self یا همون فرم هست
بنظر من استفاده از یه متغیر داخل یونیت1 کار خوبی نیست، درواقع با این کار شی گرایی رعایت نشده. بهترین راهکار اینه که عملیات آزاد شدن داخل کلاس خودش باشه، مثلا تو
TForm2.OnClose
مشکلی در آزاد کردن کلاس وجود نداره، کلاس فرم که با Action = Free آزاد میشه
مشکل اینجاست که متغیر frm که اشاره گر به کلاس هست باید nil بشه تا تابع Assigned وقتی اون رو بررسی میکنه، مقدار False برگردونه
از داخل کلاس، شما دسترسی به اشاره گری که به کلاس ساخته شده اشاره می کنه ندارید
استفاده از متغیر Global هم ارتباطی به شی گرایی نداره !

اینکه دوستان سعی می کنند در بحثها شرکت کنند چیز مثبتیه، اما اینکه هر چیزی که به ذهنمون رسید رو با اطمینان بیان کنیم و در مورد درست بودنش تحقیق نکرده باشیم، ممکنه سایر دوستانی که در ابتدای راه یادگیری هستند رو به مسیر اشتباهی ببره
به هر حال ...

راه های زیادی وجود داره، استفاده از متغیر عمومی هم راه ساده ایه که شما رو درگیر بحث اشاره گرها نکنه تا اشتباهاتی مثل کدهای درون پستهای بالا رخ نده
مثلا راه دیگه اینه که شما فرمهای Screen رو چک کنید و وجود Form2 رو بررسی کنید، مثال :

procedure TForm1.Button1Click(Sender: TObject);
var
I : Integer;
FormShowing : Boolean;
begin
FormShowing := False;
for I := 0 to Screen.FormCount - 1 do
begin
if Screen.Forms[I].ClassName = 'TForm2' then
begin
FormShowing := True;
Break;
end;
end;

if not FormShowing then
begin
frm := TForm2.Create(nil);
frm.Show;

frm := nil;
end
end;

...

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


امیدوارم این بحث ادامه پیدا نکنه
موفق باشید