Comp. yazarken kullandığı bileşenler free edilmez mi?
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Comp. yazarken kullandığı bileşenler free edilmez mi?
Selam arkadaşlar.
Comp yazarken, mesela bileşene resim özelliği katmak için, FGlyph: TBitmap şeklinde tanımlama yapıp
property Glyph: TBitmap read FGlyph write SetGlyph şeklinde property tanımlıyorum.
Compenent'in create yordamını inherit edip FGlyph := TBitmap.Create şeklinde create ediyorum. Buraya kadar her şey normal. Ama 'Create ettiğini free etmeyen bizden değildir.' diyerek bileşenin destroy yordamını da inherit ediyorum ve 'FGlyph.Free' yazıyorum ve sonucunda bileşeni eklediğim program kapanırken (destroy tetiklendiğinde) 'BileşenAdi has no parent window' şeklinde hata veriyor. FGlyph'yi free etmezsem herhangi bir sıkıntı yok.
Yazdığımız bileşende create ettiğimiz nesnelerin, bileşen free edilirken kendiliğinde free edildiğini, hatta ben free etiğimde bileşen de free etmeye çalışırken başaramadığını ve bu nedenle hata verdiğini öğrendim.
Fakat, Jedi'nin bir bileşenini inceledim. Aynı şekilde FGlyph tanımlanmış, create edilmiş ve free edilmiş, hiç bir sıkıntı yok.
Ben nerde hata yapıyor olabilirim, yorumlarınızı bekliyorum.
Teşekkürler, kolay gele...
Comp yazarken, mesela bileşene resim özelliği katmak için, FGlyph: TBitmap şeklinde tanımlama yapıp
property Glyph: TBitmap read FGlyph write SetGlyph şeklinde property tanımlıyorum.
Compenent'in create yordamını inherit edip FGlyph := TBitmap.Create şeklinde create ediyorum. Buraya kadar her şey normal. Ama 'Create ettiğini free etmeyen bizden değildir.' diyerek bileşenin destroy yordamını da inherit ediyorum ve 'FGlyph.Free' yazıyorum ve sonucunda bileşeni eklediğim program kapanırken (destroy tetiklendiğinde) 'BileşenAdi has no parent window' şeklinde hata veriyor. FGlyph'yi free etmezsem herhangi bir sıkıntı yok.
Yazdığımız bileşende create ettiğimiz nesnelerin, bileşen free edilirken kendiliğinde free edildiğini, hatta ben free etiğimde bileşen de free etmeye çalışırken başaramadığını ve bu nedenle hata verdiğini öğrendim.
Fakat, Jedi'nin bir bileşenini inceledim. Aynı şekilde FGlyph tanımlanmış, create edilmiş ve free edilmiş, hiç bir sıkıntı yok.
Ben nerde hata yapıyor olabilirim, yorumlarınızı bekliyorum.
Teşekkürler, kolay gele...
Kod: Tümünü seç
property Glyph: TBitmap read FGlyph write SetGlyph
destroy u inherit etmene gerek yok, işin bittiğinde property nin kullandığı değişkeni free edeceksin -ki bu muhtemelen senin yazdığın bileşen in destroy udur. yada null olmayan bir değer içeren property yi sıfırlamak için vs
iqprog, evet, önce FGlyph'yi free ediyorum, sonra inherit...

Ama jedi'de FGlyph'yi free etmişler, property tanımlama ve property'nin kullandığı bileşeni(FGlyph) tanımlama aynı benim yaptığım şekilde. Onların kodu hata vermiyo, bana ne gıcıklığı var bu delphi'ninlazio yazdı:burda TBitmap tipinden bir property tanımlıyorsun, ve bir değişken nasıl kullanılıyorsa o şekilde kullanırsın bu property yi.Kod: Tümünü seç
property Glyph: TBitmap read FGlyph write SetGlyph
destroy u inherit etmene gerek yok, işin bittiğinde property nin kullandığı değişkeni free edeceksin -ki bu muhtemelen senin yazdığın bileşen in destroy udur. yada null olmayan bir değer içeren property yi sıfırlamak için vs

FGlyph tabiki free edilecek fakat ben neden ve nasılulu coder yazdı:Ama jedi'de FGlyph'yi free etmişler, property tanımlama ve property'nin kullandığı bileşeni(FGlyph) tanımlama aynı benim yaptığım şekilde. Onların kodu hata vermiyo, bana ne gıcıklığı var bu delphi'ninlazio yazdı:burda TBitmap tipinden bir property tanımlıyorsun, ve bir değişken nasıl kullanılıyorsa o şekilde kullanırsın bu property yi.Kod: Tümünü seç
property Glyph: TBitmap read FGlyph write SetGlyph
destroy u inherit etmene gerek yok, işin bittiğinde property nin kullandığı değişkeni free edeceksin -ki bu muhtemelen senin yazdığın bileşen in destroy udur. yada null olmayan bir değer içeren property yi sıfırlamak için vs

FGlyph kullanmadan önce nasıl create ediyorsan işin bittiğinde de free edersin.
Selam,
Emin değilim ama sorun şöyle bir şey olabilir
Eğer işlemi bu şekilde yaptıysanız, free ederken sorun çıkacaktır, çünkü Value ile gönderilen bitmap büyük ihtimalle ana programda da free ediliyordur.
Componentin bellek yönetimi açısından bu daha doğru. Hatta normalde buna benzer propertylerde Set fonksiyonu vermemek daha mantıklı. Çünkü programcı açısından Set edildikten sonra nesnenin ne yapılacağı belli değil. Örneğin;
Bu ikinci kullanım
Bu da üçüncü kullanım
SetGlyph fonksiyonu eklerseniz ilk kullanım da geçerli olacak ve A bitmapini kimin sileceği problem olacak. Örnekte ben sildim, çünkü componentin TBitmap.Assign kullandığını düşündüm. Ama FGlyph := Value kullanıyorsa işte o zaman program çökecektir.
Biraz karıştırdım, ama umarım anlamışsınızdır.
Kolay gelsin,
Bahadır Alkaç
Emin değilim ama sorun şöyle bir şey olabilir
Kod: Tümünü seç
procedure TMyComponent.SetGlyph(Value :TBitmap)
begin
FGlyph := Value;
end;
Kod: Tümünü seç
FGlyph.Assign(Value);
Kod: Tümünü seç
var
A:TBitmap;
begin
A := TBitmap.Create;
A.LoadFromFile('Hebele.bmp');
MyComponent.Glyph := A;
A.Free;
end;
Kod: Tümünü seç
begin
MyComponent.Glyph.LoadFromFile('Hebele.bmp');
end;
Kod: Tümünü seç
var
A:TBitmap;
begin
A := TBitmap.Create;
A.LoadFromFile('Hebele.bmp');
MyComponent.Glyph.Assign(A);
A.Free;
end;
Biraz karıştırdım, ama umarım anlamışsınızdır.
Kolay gelsin,
Bahadır Alkaç
@opt2000, sanırım ne demek istediğinizi anladım, fakat FGlyph değiştiğinde işletmem gereken kodlar var, bu nedenle prosedürle set ediyorum. Şimdi ortalık iyice karıştı
@lazio, o resme olan ihtiyacım bileşen create edildiği anda başlıyor ve destroy edilene kadar devam ediyor.
Yani bileşenin create prosedüründe FGlyph'yi create ediyorum, ve sık sık kullanıyorum. Her kullanacağımda create edip sonra free edemem.
İlginiz için teşekkürler.
(Hala free edemiyorum.)

@lazio, o resme olan ihtiyacım bileşen create edildiği anda başlıyor ve destroy edilene kadar devam ediyor.

Yani bileşenin create prosedüründe FGlyph'yi create ediyorum, ve sık sık kullanıyorum. Her kullanacağımda create edip sonra free edemem.
İlginiz için teşekkürler.
(Hala free edemiyorum.)
Selam,
Bunun da aslında çok basit bir çözümü var. Private bir değişken tanımlayın, örneğin CustomGlyph gibi. Contructor'da CustomGlyph değişkenini false yapın. Daha sonra da
Benzer bir kontrolü de destructor'da yapın. Ama bu kullanımda şuna dikkat etmeniz gerekiyor, Application (component değil) Glyph değişkenini free etmeli!
İkinci bir yöntem daha var aslında, ama bilgisayarımda Delphi olmadığı için kontrol veya test edemiyorum. TBitmap sınıfının OnChange eventinin olması gerekiyor (Büyük ihtimalle vardır). FGlyph bitmapinin OnChange kısmı ile FGlyph değiştiğinde çalışması gereken kodları çalıştırabilirsiniz. Böylece bellek kullanımı ile ilgili bir önceki mesajda bahsetmeye çalıştığım karışıklığın da önüne geçilir. TBitmap.OnChange eventi var mı hatırlamıyorum.
Kolay gelsin,
Bahadır Alkaç
Bunun da aslında çok basit bir çözümü var. Private bir değişken tanımlayın, örneğin CustomGlyph gibi. Contructor'da CustomGlyph değişkenini false yapın. Daha sonra da
Kod: Tümünü seç
procedure SetGlyph(Value:TBitmap)
begin
if not CustomGlyph then
FGlyph.Free;
//Diğer kodlar
end;
İkinci bir yöntem daha var aslında, ama bilgisayarımda Delphi olmadığı için kontrol veya test edemiyorum. TBitmap sınıfının OnChange eventinin olması gerekiyor (Büyük ihtimalle vardır). FGlyph bitmapinin OnChange kısmı ile FGlyph değiştiğinde çalışması gereken kodları çalıştırabilirsiniz. Böylece bellek kullanımı ile ilgili bir önceki mesajda bahsetmeye çalıştığım karışıklığın da önüne geçilir. TBitmap.OnChange eventi var mı hatırlamıyorum.
Kolay gelsin,
Bahadır Alkaç
İşler iyice karışmış burada. 
Örnek bir kod vereyim.
Bu kod ile constructor'da TBitmap instance'ı oluşturup FBitmap'a atamasını yapıyoruz. destructor'da ise Önce FBitmap i Free edip ardından kendi bileşenimizi Free edecek Destroy method'unu çağırıyoruz.
Yani bileşen içinde bir bileşen oluşturduğumuzda bunu da Free etmemiz gerekir. Etmemiz gerekmez kısmını yanlış anlamışsın. Unutma ki oluşturduğun her objenin Free edilmesi de senin sorumluluğundadır.

Örnek bir kod vereyim.
Kod: Tümünü seç
type
TMyComponent = class(TComponent)
private
FBitmap: TBitmap;
public
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
end;
constructor TMyComponent.Create(AOwner:TComponent); override;
begin
inherited Create(AOwner);
FBitmap:= TBitmap.Create;
end;
destructor TMyComponent.Destroy;
begin
FBitmap.Free;
inherited Destroy;
end;
Yani bileşen içinde bir bileşen oluşturduğumuzda bunu da Free etmemiz gerekir. Etmemiz gerekmez kısmını yanlış anlamışsın. Unutma ki oluşturduğun her objenin Free edilmesi de senin sorumluluğundadır.