Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
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?
Yorumları: 91
Konuları: 13
Kayıt Tarihi: 25-06-2017
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
Yorumları: 1.499
Konuları: 83
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 12.314 Üstad
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...
Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
(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?
Yorumları: 1.499
Konuları: 83
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 12.314 Üstad
(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...
Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
01-05-2020, Saat: 04:48
(Son Düzenleme: 01-05-2020, Saat: 04:48, Düzenleyen: bibilen.)
(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.
Yorumları: 1.572
Konuları: 88
Kayıt Tarihi: 09-08-2016
Rep Puanı: 13.841 Üstad
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
Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
(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.
Yorumları: 1.499
Konuları: 83
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 12.314 Üstad
(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
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 101
Konuları: 7
Kayıt Tarihi: 30-06-2019
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 334 Acemi
(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 
Harika, sonuçta owner veya parent verdiysek, delphi onu kendiliğinden free edecek, bizim free etmeye uğraşmamıza gerek yok.
|