Gtk.Bin.Destroy()和Gtk.Bin.Dispose()有什么区别?
本文关键字:Gtk Bin 区别 什么 Destroy Dispose | 更新日期: 2023-09-27 18:06:32
我有一个gtk bin控件,我想删除它。这意味着我需要把它从操作记忆和窗口中移除。我通过简单地调用window. remove (child_item)来从窗口中删除它,但是我应该调用Destroy()或Dispose()还是两者都调用?按照什么顺序?
Dispose()是GObject
的一部分,在实例结束序列中用于释放引用和分离信号处理程序;在引用循环的情况下,它可以被多次调用,因此检查未设置的字段是一个很好的做法。
Destroy()是GtkWidget
的一部分,与Dispose()实现的目的类似;Destroy()在很大程度上是历史的产物,因为GObject
最初是GTK的内部类型,然后才被移出(与类型系统的其余部分一起)到GLib中。在GtkWidget
中,Destroy()作为Dispose()的默认实现的一部分被调用。
如果您想从容器中删除一个子对象,您可以简单地在容器上调用remove (child),或者在子对象上调用Destroy(): remove()将释放子对象上保存的引用,如果这是最后一个引用,这将导致小部件的销毁。在GtkWidget
上调用Destroy()将导致小部件从其父容器中删除。这两个代码路径应该是可互换的。
直接调用Dispose()是Gtk -ism: Dispose()方法主要是为了被重写,而不是直接调用。
我查看了GtkSharp 3.24.24.34源代码。我检查了几个小部件,包括Bin
和它的父部件,Dispose()
和Destroy()
方法定义的唯一地方是Widget
类。
如下所示,两种方法非常相似:
private bool destroyed;
protected override void Dispose (bool disposing)
{
if (Handle == IntPtr.Zero)
return;
if (disposing && !destroyed && IsToplevel)
{
//If this is a TopLevel widget, then we do not hold a ref, only a toggle ref.
//Freeing our toggle ref expects a normal ref to exist, and therefore does not check if the object still exists.
//Take a ref here and let our toggle ref unref it.
g_object_ref (Handle);
gtk_widget_destroy (Handle);
destroyed = true;
}
InternalDestroyed -= NativeDestroyHandler;
base.Dispose (disposing);
}
public virtual void Destroy ()
{
if (Handle == IntPtr.Zero)
return;
if (destroyed)
return;
gtk_widget_destroy (Handle);
destroyed = true;
InternalDestroyed -= NativeDestroyHandler;
}
我能看到的最大区别是Dispose()
方法只对顶级小部件调用gtk_widget_destroy()
函数,而根据Gtk文档,顶级小部件只有Window
和Invisible
。如果我理解正确的话,Dispose()
方法(几乎)等于Destroy()
方法,仅用于顶级部件,如Window
。
根据这个发现,当我想摆脱单个小部件时,我更愿意调用Destroy()
方法,并将Dispose()
方法留给窗口关闭时的最终清理,这是由垃圾收集器完成的。