RefCounted ve Node Karşılaştırması
Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 43 / 65.
Her nesne, serbest bırakılana kadar bellek kullanır. RefCounted ve Node farklı şekillerde serbest bırakılır.
Bir RefCounted nesnesi, ona başvuran değişkenleri, dizileri ve nesneleri sayar. Sayı sıfıra düştüğünde Godot nesneyi kendi başına serbest bırakır. Special Methods bölümündeki NOTIFICATION_PREDELETE, bu anı gösterir:
# note.gd
class_name Note
extends RefCounted
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
print("Note freed")
# main.gd
func write() -> void:
var note := Note.new()
print("Note written")
func _ready():
write() # Önce Note written, ardından Note freed
print("Back in _ready")Tek referans note olduğu için, write() sona erer ermez not serbest bırakılır.
Bir Node sayılmaz. Sahne ağacındaki bir düğüm, üst öğesiyle birlikte serbest bırakılır ve oyun sona erdiğinde ağacın tamamı serbest bırakılır. Ağaçtan çıkardığınız veya ağaca hiç eklemediğiniz bir düğümü sizin serbest bırakmanız gerekir:
crate.free() # tüm alt öğeleriyle birlikte hemen serbest bırakılır
crate.queue_free() # geçerli karenin sonunda serbest bırakılırfree() sonrasında düğüm artık yoktur: is_instance_valid(crate), false döndürür ve üzerinde bir yöntem çağırmak hatadır. Bu karede başka kodlar düğümü hâlâ kullanıyor olabileceğinden queue_free() güvenli seçimdir; ancak bu kare sona erene kadar düğüm ağaçta kalır ve get_child_count() içinde sayılmaya devam eder.
Hiç serbest bırakılmayan bir düğüm, bir bellek sızıntısıdır: program sona erdiğinde Godot, "ObjectDB instances were leaked at exit" bildirimini verir. İki RefCounted nesnesi birbirine başvurduğunda onlar da sızıntı yapar, çünkü hiçbirinin sayacı sıfıra ulaşamaz. Bağlantıyı yalnızca tek yönde saklayın ya da nesne yerine bir ad saklayın.
Veriler için RefCounted kullan: öğeler, puanlar, kayıtlar. Sahne ağacında yaşayan şeyler için Node kullan.
Görev
KolayBir Wave düğümü, düşmanlarını alt düğümleri olarak tutar. enemy.gd tamamlanmıştır: Enemy.new("Goblin", 5), 5 HP'ye sahip ve Goblin adlı bir düşman düğümü oluşturur. Wave için üç yöntemi yaz:
spawn(enemy_name, hp)yeni bir düşmanı alt düğüm olarak ekler. Bu ada sahip bir alt düğüm varsaOrc is already hereyazdırır ve hiçbir şey oluşturmaz.hit(enemy_name, damage)o düşmanınhpdeğerini düşürür veOrc has 8 HPyazdırır. HP değeri0veya daha az olduğundaOrc defeatedyazdırır ve düşmanı hemen ve kalıcı olarak kaldırır: sonrakialive()çağrısı onu saymamalıdır. Mevcut olmayan bir ad içinNo Orc hereyazdırılır.alive()geriye kalan düşman sayısını döndürür.
Her düğüm serbest bırakılmalıdır: program sona erdiğinde herhangi bir bellek sızıntısı testi başarısız kılar. Sağlanan kod dalga düğümünü sahne ağacına ekler, ardından kaç komut geleceğini okur (spawn Goblin 5, hit Goblin 6, count) ve geriye kalan düşmanları yazdırır. spawn Goblin 5, spawn Orc 12, hit Goblin 6, count, hit Goblin 1, spawn Orc 3, hit Orc 4 komutları için şu çıktıyı verir:
Goblin defeated
Enemies: 1
No Goblin here
Orc is already here
Orc has 8 HP
Enemies left: 1Kodunu wave.gd ve enemy.gd dosyalarına yaz. main.gd, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
extends Node
func _ready():
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
var wave := Wave.new()
add_child(wave)
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "spawn":
wave.spawn(parts[1], int(parts[2]))
elif parts[0] == "hit":
wave.hit(parts[1], int(parts[2]))
else:
print("Enemies: ", wave.alive())
print("Enemies left: ", wave.alive())
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Nesne Yönelimli Programlamanın Temelleri
Harici DosyalarNesne Yönelimli Programlamaya GirişSınıflar ve Nesnelerself Anahtar KelimesiMetotlarÖzelliklerKurucu (_init)Tekrar - Basit Hesap Makinesi4Çok Biçimlilik
Metot Ezme Konusuna Yeniden BakışÖrdek TiplemesiSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı7Sinyaller
Sinyal Nedir?Tanımlama ve Sinyal GöndermeSinyallere BağlanmaArgümanlı SinyallerTekrar - Sağlık Sistemi10Tasarım Kalıpları 2. Bölüm
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik Kalıp2Sınıf Özellikleri
Örnek ve Statik DeğişkenlerStatik FonksiyonlarÖzellik AyarlayıcılarıÖzellik AlıcılarıGeleneksel Olarak ÖzelTekrar - Banka Hesabı Yöneticisi5Kapsülleme
Public ve Private ÜyelerSetter'larla DoğrulamaBilgi GizlemeSalt Okunur ÖzelliklerTekrar - Öğrenci Kayıt Sistemi8İleri OOP Kavramları
Composition ve Inheritance Karşılaştırmasıİç SınıflarBileşen Olarak DüğümlerRefCounted ve Node KarşılaştırmasıSınıflarda Enum’larKendi başına pratik yap: Online GDScript derleyicisi