Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Boş yere free etmeye uğraştığımı düşünüyorum.
#1
Geçen farkettim ki, yıllardır hafızayı şişirmeyim diye yaptığım şeyi fazladan yapıyorum. Ama yine de içim rahat etmedi sizlerin de fikrini almak istedim.

Konu şudur;
Adım 1 : Runtime'de bir ya da bir sürü control create ettiğinizi düşünün, bunların parent'ı form ya da herhangi bir panel vb.
Adım 2 : Formun kapatılıp free edildiğini düşünün. Ben onclose olayında runtime'da yarattığım adım1'deki controlleri free eden kodlar yazarım.

Sonuçta free edilen formun child'ları da kendiliğinden free ediliyor. bunları onclose'da free etmeye uğraşmaya gerek yok aslında, boş yere uğraşıyorum free etmeye haksız mıyım?
Cevapla
#2
Bence haklısınız.
Cevapla
#3
TComponent’ten türeyen sınıflarınızı oluştururken bir Owner veriyorsanız, evet gerek yok.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
(01-05-2020, Saat: 04:33)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: TComponent’ten türeyen sınıflarınızı oluştururken bir Owner veriyorsanız, evet gerek yok.

owner demişsiniz ama parent olmasın o?
Cevapla
#5
(01-05-2020, Saat: 04:36)bibilen Adlı Kullanıcıdan Alıntı:
(01-05-2020, Saat: 04:33)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: TComponent’ten türeyen sınıflarınızı oluştururken bir Owner veriyorsanız, evet gerek yok.

owner demişsiniz ama parent olmasın o?

Hayır, parent farklıdır. Owner’ı araştırmanızı öneririm.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#6
(01-05-2020, Saat: 04:39)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı:
(01-05-2020, Saat: 04:36)bibilen Adlı Kullanıcıdan Alıntı: owner demişsiniz ama parent olmasın o?

Hayır, parent farklıdır. Owner’ı araştırmanızı öneririm.

owner'ı biliyorum da, controlü create ederken owner olarak verdiğimiz nesneyi aynı zamanda parent'a da veriyoruz ya, genelde bu ikisi aynı oluyor, değişik bir uygulama ihtiyacı olmuyorsa. ama burada free olayında anahtar property owner'mış evet teşekkürler.
Cevapla
#7
Evet asıl sahip, adı üzerinde Owner. Ama farklı durumlar da olabilir. 
Mesela bileşeni oluştururken owner'ını nil atayabilirsiniz. Yada owner'ı farklı, parent'ı farklı tanımlarsınız.
Owner'ı nil atadınız diyelim: bu durumda Parent'ı destroy ederseniz yine oluşturduğumuz bileşen güzelce free edilir.
Aynı şekilde owner ve parent farklı ve önce parent destroy edilirse, yine sorun olmaz. Parent'ın destroyunda bileşenimiz free edilir ve bu esnada da owner'a haber verilir ki owner destroy edilirken aynı bileşeni tekrar free etmeye çalışmasın.
There's no place like 127.0.0.1
WWW
Cevapla
#8
(01-05-2020, Saat: 12:09)SimaWB Adlı Kullanıcıdan Alıntı: Evet asıl sahip, adı üzerinde Owner. Ama farklı durumlar da olabilir. 
Mesela bileşeni oluştururken owner'ını nil atayabilirsiniz. Yada owner'ı farklı, parent'ı farklı tanımlarsınız.
Owner'ı nil atadınız diyelim: bu durumda Parent'ı destroy ederseniz yine oluşturduğumuz bileşen güzelce free edilir.
Aynı şekilde owner ve parent farklı ve önce parent destroy edilirse, yine sorun olmaz. Parent'ın destroyunda bileşenimiz free edilir ve bu esnada da owner'a haber verilir ki owner destroy edilirken aynı bileşeni tekrar free etmeye çalışmasın.

aaa çok ilginç benim en başta düşüncem parent'ın free ettiği idi, sonra owner free ediyor diye anladım, ama şimdi görüyorum ki ikisi de o işi görüyor. harika çok teşekkür ederim bu bilgi için. yıllardır delphi kullanırım bu kendiliğinden free olma konusunu hiç ayrıntısıyla inceleme ihtiyacım olmamış nedense. ben kodla kendim free ediyordum işim bitince runtimeda create ettiklerimi.
tekrar teşekkürler.
Cevapla
#9
(01-05-2020, Saat: 12:17)bibilen Adlı Kullanıcıdan Alıntı:
(01-05-2020, Saat: 12:09)SimaWB Adlı Kullanıcıdan Alıntı: Evet asıl sahip, adı üzerinde Owner. Ama farklı durumlar da olabilir. 
Mesela bileşeni oluştururken owner'ını nil atayabilirsiniz. Yada owner'ı farklı, parent'ı farklı tanımlarsınız.
Owner'ı nil atadınız diyelim: bu durumda Parent'ı destroy ederseniz yine oluşturduğumuz bileşen güzelce free edilir.
Aynı şekilde owner ve parent farklı ve önce parent destroy edilirse, yine sorun olmaz. Parent'ın destroyunda bileşenimiz free edilir ve bu esnada da owner'a haber verilir ki owner destroy edilirken aynı bileşeni tekrar free etmeye çalışmasın.

aaa çok ilginç benim en başta düşüncem parent'ın free ettiği idi, sonra owner free ediyor diye anladım, ama şimdi görüyorum ki ikisi de o işi görüyor. harika çok teşekkür ederim bu bilgi için. yıllardır delphi kullanırım bu kendiliğinden free olma konusunu hiç ayrıntısıyla inceleme ihtiyacım olmamış nedense. ben kodla kendim free ediyordum işim bitince runtimeda create ettiklerimi.
tekrar teşekkürler.

Merhaba, aslında çok güzel bir mekanizma var Delphi'de. Hep bahsettiğimiz gibi; Delphi bir çok zorluğu programcıdan saklamayı maharetli bir şekilde başarabiliyor.

Bir TComponent türevini Create ederken, Owner vermezseniz ve sadece bir başka TWinControl'ün Parent'ı olarak verirseniz; bu durumda Parent olarak atanan component Destroy olurken aşağıdaki koddan dolayı çocuk nesneleri yok edecektir:

  
while I <> 0 do
  begin
   Instance := Controls[I - 1];
   Remove(Instance);
   Instance.Destroy;
   I := ControlCount;
 end;

Görüldüğü gibi, ilgili görsel kontrol üzerindki tüm görsel kontroller için ilgili kontrolün Destroy metodu çağrılmaktadır. Diyelim ki; bir component'i create ederken bir başka component'i Owner olarak verdiniz ama Parent ataması yapmadınız; bu durumda da oluşturduğunuz kontrol herhangi bir kontrol'ün bir alt üyesi olmadığı için hiç bir kontrol tarafından yukarıdaki döngü ile serbest bırakılamayacak, bu sefer de TComponent'in Destroy'undaki DestroyComponents metodu vasıtası ile yok edilebilecektir:

destructor TComponent.Destroy;
begin
 Destroying;
 RemoveFreeNotifications;
 DestroyComponents;
 if FOwner <> nil then FOwner.RemoveComponent(Self);
 FObservers.Free;
 inherited Destroy;
end;

procedure TComponent.DestroyComponents;
var
  Instance: TComponent;
begin
  FreeAndNil(FSortedComponents);
  while FComponents <> nil do
  begin
    Instance := FComponents.Last;
    if (csFreeNotification in Instance.FComponentState)
      or (FComponentState * [csDesigning, csInline] = [csDesigning, csInline]) then
      RemoveComponent(Instance)
    else
      Remove(Instance);
    Instance.DisposeOf;
  end;
end;

Yukarıda gördüğünüz gibi; FComponents listesi içinden bu component'in sahip olduğu tüm component'ler alınıp tek tek yok ediliyor. Peki oluşturduğumuz component FComponents içine ne zaman giriyor diye soruyorsanız, bunun için aşağıdaki hiyerarşiyi takip etmeniz gerekir:

constructor TComponent.Create(AOwner: TComponent);
begin
 FComponentStyle := [csInheritable];
 if AOwner <> nil then AOwner.InsertComponent(Self);
end;

procedure TComponent.InsertComponent(const AComponent: TComponent);
var
  Notifier: IDesignerNotify;
begin
  GetComponentDesigner(Self, Notifier);
  if Notifier <> nil then
    Notifier.CanInsertComponent(AComponent);
  AComponent.ValidateContainer(Self);
  if AComponent.FOwner <> nil then
    AComponent.FOwner.RemoveComponent(AComponent);
  ValidateRename(AComponent, '', AComponent.FName);
  Insert(AComponent);
  AComponent.SetReference(True);
  if csDesigning in ComponentState then
    AComponent.SetDesigning(True);
  Notification(AComponent, opInsert);
end;

procedure TComponent.Insert(AComponent: TComponent);
begin
  if FComponents = nil then FComponents := TList<TComponent>.Create;
  FComponents.Add(AComponent);
  if FSortedComponents <> nil then
    AddSortedComponent(AComponent);
  AComponent.FOwner := Self;
end;

Sihirli gibi ama değil, sadece harika bir tasarım Wink
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#10
(02-05-2020, Saat: 05:23)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı:
(01-05-2020, Saat: 12:17)bibilen Adlı Kullanıcıdan Alıntı: aaa çok ilginç benim en başta düşüncem parent'ın free ettiği idi, sonra owner free ediyor diye anladım, ama şimdi görüyorum ki ikisi de o işi görüyor. harika çok teşekkür ederim bu bilgi için. yıllardır delphi kullanırım bu kendiliğinden free olma konusunu hiç ayrıntısıyla inceleme ihtiyacım olmamış nedense. ben kodla kendim free ediyordum işim bitince runtimeda create ettiklerimi.
tekrar teşekkürler.

Merhaba, aslında çok güzel bir mekanizma var Delphi'de. Hep bahsettiğimiz gibi; Delphi bir çok zorluğu programcıdan saklamayı maharetli bir şekilde başarabiliyor.

Bir TComponent türevini Create ederken, Owner vermezseniz ve sadece bir başka TWinControl'ün Parent'ı olarak verirseniz; bu durumda Parent olarak atanan component Destroy olurken aşağıdaki koddan dolayı çocuk nesneleri yok edecektir:

  
while I <> 0 do
  begin
   Instance := Controls[I - 1];
   Remove(Instance);
   Instance.Destroy;
   I := ControlCount;
 end;

Görüldüğü gibi, ilgili görsel kontrol üzerindki tüm görsel kontroller için ilgili kontrolün Destroy metodu çağrılmaktadır. Diyelim ki; bir component'i create ederken bir başka component'i Owner olarak verdiniz ama Parent ataması yapmadınız; bu durumda da oluşturduğunuz kontrol herhangi bir kontrol'ün bir alt üyesi olmadığı için hiç bir kontrol tarafından yukarıdaki döngü ile serbest bırakılamayacak, bu sefer de TComponent'in Destroy'undaki DestroyComponents metodu vasıtası ile yok edilebilecektir:

destructor TComponent.Destroy;
begin
 Destroying;
 RemoveFreeNotifications;
 DestroyComponents;
 if FOwner <> nil then FOwner.RemoveComponent(Self);
 FObservers.Free;
 inherited Destroy;
end;

procedure TComponent.DestroyComponents;
var
  Instance: TComponent;
begin
  FreeAndNil(FSortedComponents);
  while FComponents <> nil do
  begin
    Instance := FComponents.Last;
    if (csFreeNotification in Instance.FComponentState)
      or (FComponentState * [csDesigning, csInline] = [csDesigning, csInline]) then
      RemoveComponent(Instance)
    else
      Remove(Instance);
    Instance.DisposeOf;
  end;
end;

Yukarıda gördüğünüz gibi; FComponents listesi içinden bu component'in sahip olduğu tüm component'ler alınıp tek tek yok ediliyor. Peki oluşturduğumuz component FComponents içine ne zaman giriyor diye soruyorsanız, bunun için aşağıdaki hiyerarşiyi takip etmeniz gerekir:

constructor TComponent.Create(AOwner: TComponent);
begin
 FComponentStyle := [csInheritable];
 if AOwner <> nil then AOwner.InsertComponent(Self);
end;

procedure TComponent.InsertComponent(const AComponent: TComponent);
var
  Notifier: IDesignerNotify;
begin
  GetComponentDesigner(Self, Notifier);
  if Notifier <> nil then
    Notifier.CanInsertComponent(AComponent);
  AComponent.ValidateContainer(Self);
  if AComponent.FOwner <> nil then
    AComponent.FOwner.RemoveComponent(AComponent);
  ValidateRename(AComponent, '', AComponent.FName);
  Insert(AComponent);
  AComponent.SetReference(True);
  if csDesigning in ComponentState then
    AComponent.SetDesigning(True);
  Notification(AComponent, opInsert);
end;

procedure TComponent.Insert(AComponent: TComponent);
begin
  if FComponents = nil then FComponents := TList<TComponent>.Create;
  FComponents.Add(AComponent);
  if FSortedComponents <> nil then
    AddSortedComponent(AComponent);
  AComponent.FOwner := Self;
end;

Sihirli gibi ama değil, sadece harika bir tasarım Wink

Harika, sonuçta owner veya parent verdiysek, delphi onu kendiliğinden free edecek, bizim free etmeye uğraşmamıza gerek yok.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Free vs FreeAndNil vs DisposeOf yanniosman 6 3.579 08-01-2024, Saat: 11:50
Son Yorum: RAD Coder
  Delphi Community Edition free info@guzelceker.com 1 2.332 29-06-2020, Saat: 11:13
Son Yorum: Fesih ARSLAN
  Datasnap free yapmama sorunu. seci20 1 2.119 24-10-2019, Saat: 08:16
Son Yorum: 3ddark
  Nesne Neden Free Olmuyor? Halil Han BADEM 3 3.407 31-07-2019, Saat: 14:28
Son Yorum: sddk
  Json Free Etmek yhackup 4 4.640 31-07-2019, Saat: 11:17
Son Yorum: Halil Han BADEM



Konuyu Okuyanlar: 1 Ziyaretçi