Comp. yazarken kullandığı bileşenler free edilmez mi?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
ulu coder
Üye
Mesajlar: 838
Kayıt: 01 Nis 2006 06:46
Konum: Ankara

Comp. yazarken kullandığı bileşenler free edilmez mi?

Mesaj gönderen ulu coder »

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...
iqprog

Mesaj gönderen iqprog »

destroy olayında FGlyph.Free lafı yukarıda inherited lafı da en altta kalacak, bu böyle mi sende?
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1527
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

Kod: Tümünü seç

property Glyph: TBitmap read FGlyph write SetGlyph
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.
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
DeveloperToolKit

..::|YeşilMavi|::..
ulu coder
Üye
Mesajlar: 838
Kayıt: 01 Nis 2006 06:46
Konum: Ankara

Mesaj gönderen ulu coder »

iqprog, evet, önce FGlyph'yi free ediyorum, sonra inherit...
lazio yazdı:

Kod: Tümünü seç

property Glyph: TBitmap read FGlyph write SetGlyph
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.
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
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'nin :shock:
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1527
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

ulu coder yazdı:
lazio yazdı:

Kod: Tümünü seç

property Glyph: TBitmap read FGlyph write SetGlyph
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.
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
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'nin :shock:
FGlyph tabiki free edilecek fakat ben neden ve nasıl :) inherit yaptığını anlayamadım.. senin bileşen bir Glyph nesnesinddenmi türüyor ki?
FGlyph kullanmadan önce nasıl create ediyorsan işin bittiğinde de free edersin.
DeveloperToolKit

..::|YeşilMavi|::..
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Mesaj gönderen Opt2000 »

Selam,

Emin değilim ama sorun şöyle bir şey olabilir

Kod: Tümünü seç

procedure TMyComponent.SetGlyph(Value :TBitmap)
begin
  FGlyph := Value;
end;
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.

Kod: Tümünü seç

  FGlyph.Assign(Value);
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;

Kod: Tümünü seç

var
  A:TBitmap;
begin
  A := TBitmap.Create;
  A.LoadFromFile('Hebele.bmp');
  MyComponent.Glyph := A;
  A.Free;
end;
Bu ikinci kullanım

Kod: Tümünü seç

begin
  MyComponent.Glyph.LoadFromFile('Hebele.bmp');
end;
Bu da üçüncü kullanım

Kod: Tümünü seç

var
  A:TBitmap;
begin
  A := TBitmap.Create;
  A.LoadFromFile('Hebele.bmp');
  MyComponent.Glyph.Assign(A);
  A.Free;
end;
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ç
ulu coder
Üye
Mesajlar: 838
Kayıt: 01 Nis 2006 06:46
Konum: Ankara

Mesaj gönderen ulu coder »

@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.)
Kullanıcı avatarı
Opt2000
Üye
Mesajlar: 216
Kayıt: 09 Tem 2003 10:04

Mesaj gönderen Opt2000 »

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

Kod: Tümünü seç

procedure SetGlyph(Value:TBitmap)
begin
  if not CustomGlyph then  
     FGlyph.Free;
  //Diğer kodlar
end;

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ç
iqprog

Mesaj gönderen iqprog »

FGlyph.Free yerine FreeAndNil(FGlyph) denersiniz mi?
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

İşler iyice karışmış burada. :)

Ö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;
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.
ulu coder
Üye
Mesajlar: 838
Kayıt: 01 Nis 2006 06:46
Konum: Ankara

Mesaj gönderen ulu coder »

Herkesten çok özür diliyorum, boşuna vaktinizi aldım.

Sonunda sorunu buldum :roll:

Delphi'yi silip yeniden yükledim.
Kodları ilk yazdığım hale getirdim (Furkan hocamın kodlarına property eklenmiş hali).

Artık hiç bi sorun yok.
Bileşen yazacam derken Delphi'yi dağıtmışım galiba, hayırlısı...

Kolay gele... :oops:
Cevapla