Mega Code Archive

 
Categories / Delphi / Forum
 

Neoturk_ e cevap

Merhaba, Bu ortamın forum olmadığını biliyorum ,ve öncelikle herkesten özür diliyorum. Sevgili neoturk , HaCKeRs arkadaşımızın 'Form Kullanımı' ile ilgili tavsiyesini yanlış anlamışa benziyorsun. Bildiğiniz gibi Delphi (veya C++Builder - bu arada ben C++Builder ile yazılım geliştiriyorum) ile bir form oluşturduğunuzda bu form 'Auto-Create forms' olarak projeye dahil olur. Anlamı şudur; programı çalıştırdığınızda bu form otomatik olarak yaratılır ve memory'de bekler. (Mdi Child tipinde ise yada projedeki tek form ise otomatik olarak visible edilir). Daha sonra siz onu Show ederek görünmesini sağlarsınız. Böyle bir formu Project-Options ve Forms sekmesini kullanarak yada proje'den gerekli satırı silerek 'Available Forms' haline dönüştürebilirsiniz.'Auto-Create forms' çoğu projede işe yarasada çoklu form kullanımı gerektiren uygulamalarda aşırı bellek tüketimine yol açar. Eğer siz bir formu 'Auto-Create forms' olarak kullanır ve daha sonra böyle kullandığınızı unutursanız hata yapabilirsiniz.Diyelimki Form2 bu tipte bir form olsun, proje çalıştırıldığında Form2 otomatik olarak yaratılır ama gösterilmez.(Form2 projedeki tek form ise MainForm özellğindedir , MainForm'lar otomatik olarak visible edilir,bu örneğimizde birden fazla form olduğunu kabul ediyorum) Sizinde bir menü yardımıyla bu formu gösterdiğinizi düşünelim.Yapmanız gereken şey formu Show (vs.) ile görüntülemektir.Create fonksiyonunu kullanırsanız gereksiz yere formun bir kopyasını oluşturursunuz.Diyelimki siz doğru yaptınız ve formu Show ettiniz.Şimdi formu kapatırken Close demeniz gerekir. Close metodunu kullanmaz formu free (vs.) ederseniz ilk bakışta görünmeyen bir hata yaparsınız. Free derseniz Formu bellekten silmiş olursunuz.Aslında bunun zararı yoktur ama aynı menüyü kullanarak formu göstermek istediğinizde hata alırsınız.Çünkü uygulama Show edilecek bir nesne bulamaz. Delphi programcıları bu hatayı sıklıkla yapar, 'Auto-Create forms' olarak tanımlanmış bir formu farkında olmadan tekrar tekrar create eder ve çoğu zamanda bellekten silmez. Bu açıdan formların istendiğinde yaratılıp daha sonra kaldırılması gerçekten ideal bir yöntemdir. (Bu yöntem aslında object oriented diller için bir kuraldır, nesneler istendiğinde üretilir ve daha sonra kaldırılır) Acemi ve dikkatsiz programcılar bu en temel kuralı çabucak atlar.Onlar için önemli olan bir şekilde programın çalışmasıdır.Neticede ortaya belleği gizlice yiyip bitiren işletim sisteminin çökmesine yol açan uygulamalar çıkar. Şimdi basit bir örnek verelim; var Form1: TForm1; begin Form1 := TForm1.Create(Application); Form1.Show; end; Burada yapılan iş şudur; TForm1 Class'ından bir nesne türetilmiş ve türetilen bu nesnenin pointer adresi TForm1 tipindeki Form1 değişkenine yerleştirilmiştir. VB gibi dillerden gelen C++ gibi dilleri sıkıcı ve zor bulan çoğu programcı burda yapılan işi bir kalıp olarak öğrenmiştir.Onlar için burada yapılan sadece Form1 nesnesini yaratmaktır. Onlar için Form1 değişkeni yaratılmış olan formun kendisidir. Halbuki Form1 değişkeninin belli bir bellek bölgesinin adresini tutmaktan başka bir görevi yoktur. Object Oriented dillerde herşey bu yapı üzerinden yürür (nesnenin şablonunu yap (Class vs.) ,gerektiğinde türet ve yok et) Çoğu Delphi programcısı yarattığı nesneleri yok etmez .Bu aslında VCL gibi oldukça kullanışlı ve basit bir bir nesne çatısı kurduğu için Borland'ın suçudur.Birçok Delphi bileşeni TComponent adındaki temel bir nesne sınıfından türetilmiştir. (Aslında tüm VCL nesneleri TObject denen bir temel bir sınıf'tan üretilir. Örneğin TButton sınıfı sırasıyla; TObject TPersistent TComponent TControl TWinControl TButtonControl TButton sınıflarından türetilmişitir.) TComponent sınıfı şu kolaylığı sağlar;Siz bir form yaratır ve o form üzerine bir button koyarsınız. İşiniz bittiğinde formu Free edersiniz.Buraya kadar herşey güzeldir, peki ama button kontrolü ne oldu? Hala hafızada'mı duruyor? Button kontrolü bizim yerimize hafızadan silinmiştir.Bunu sağlayan TComponent sınıfının Owner ilişkisidir. Hatırlarsınız bir nesneyi yaratırken şöyle yaparız. (Mesela bir Button yaratırken) ... Button1:=TButton.Create(Form1); ... ... Sınıfın Create üye işlevi yine TComponent sınıfından Owner adında bir parametre alır. (Bu örnek'te Button1 kontrolünün Owner'ı yani sahibi Form1 kontrolüdür) Yani nesneyi kabaca bir başka nesneye bağlamış olursunuz.Ve daha sonra Form1 'kontrolünü yok ettiğnizde ona bağlı tüm kontrollerde yok edilir. VCL uygulamalarıda Application adı verilen bir nesne üzerinden gelişitirilir. Siz formları yaratırken Application nesnesini owner olarak belirlersiniz (genellikle). (Yukarıdaki örneği hatırlayın). Bir uygulama sona erdiğinde aslında Application nesnesi sona erdirilimiş dolayısıyla ona bağlı diğer nesnelerde (form vs.) otomatik olarak yok edilmiş olur. Son olarak FreeAndNil ile ilgilide birşeyler söylemek istiyorum; Bir nesneyi Free ettiğinizi düşünelim ,Örneğin; ... Button1.Free; ... Burada Button1 pointer'ının gösterdiği bellek alanını silmiş olursunuz ama Button1 pointer'ının içeriği hala olmayan bir bellek alanını göstermektedir. Bu programlamada hataya yol açabilir.Doğru olan yöntem şudur; ... Button1.Free; Button1:=nil; ... Böylece hem bellek alanını hemde pointer'ın içeriğini temizlemiş olursunuz. FreeAndNil bu iki işlemi tek komuta indirger. ... FreeAndNil(Button1); ... VCL kaynak kodlarını incelerseniz nesnelerin FreeAndNil metodu ile yok edildiğini görürsünüz. Destroy üye işlevi VCL de nesnelerin yokedilmesi sırasında otomatik olarak zaten çağrılır. Aslında Create ve Destroy işlevleri C++'da constructor ve destructor olarak bilinen yapıcı ve yıkıcı fonksiyonlardır.Ve direkt olarak çağrılamazlar. Delphi (pascal) bu kuralı çiğner , yapıcı ve yıkıcı fonksiyonları direkt olarak çağırmanız mümkündür.Ama bu yapıcı (Create) için bir yöntem olsada yıkıcı (Destroy) için bir yöntem değildir. VCL kontrolleri Free ile yokedilir.Siz Free dediğinizde zaten Destroy üye işlevi otomatik olarak çağrılır.Destroy işlevini kullanırken her zaman dikkatli olmanız gerekir. (Free işlevi bir nesneyi yok etmeden önce öyle bir nesnenin olup olmadığını kontrol eder eğer nesne mevcutsa Destroy işlevini çağırır) ------------------------------------------------------------------------------------------------- Serkan ÖZLEM